Alles über Computer lernen

Also manche Leute sind hier schon sehr negativ mit ihren Kommentaren. Wenn man wissbegierig ist und viel Zeit hinein investiert kann man schon sehr weit kommen. Erlerntes vergisst man ja auch selten komplett. Zumindest hat man noch eine ungefähre Idee, wenn man es mal wieder zu Gesicht bekommt (vorrausgesetzt man hat damals Arbeit hineingesteckt).

Und ich denke genau hierum geht es dem TE auch eigentlich: einen Überblick über alle relevanten Themen zu bekommen, um eine fundierte Basis zu haben. Einen Anspruch, den ich eigentlich an jeden mehr oder weniger stellen würde, der behauptet etwas studiert zu haben. Das hat ja nichts damit zu tun, dass man jegliche Paper der letzten hundert Jahre auswendig aufsagen kann. Die allermeisten Konzepte sind über die Zeit halbwegs gleich geblieben oder sind Weiterentwicklungen. Hier reicht es oft, wenn man die Endergebnisse der Forschung kennt und halbwegs versteht, um was es geht. Natürlich ist auch das eine Herausforderung, aber es besteht schon ein Unterschied zwischen "ich würde gerne wissen, was DNA ungefähr ist und halbwegs verstehen, was sie macht" und "ich möchte das komplette Humangenom per Hand entschlüsseln".
Wer erwartet, dass er in allen Forschungsgebieten zum absoluten Experten werden und 100 Nobelpreise gewinnen wird .. naja dem ist auch nicht mehr zu helfen.

Beim Verständnis von Computern und/oder Informatik gibt es gleich von Anfang an schon ein paar Entscheidungen, die man treffen muss. Irgendwie muss man an die Sache rangehen. So etwas wie Turing-Maschinen und formale Grammatiken, Logik usw. gehören in die Sparte der theoretischen Informatik. Sehr hilfreich in vielen Dingen, aber nicht unbedingt nötig, um die Hardware zu verstehen. Geht es um die Entwicklung von vernünftigen Datenstrukturen und Algorithmen ist es jedoch völlig unvermeidbar hiermit zu beschäftigen. Hier würde ich dann eher hierauf meinen Hauptaugenmerk legen, als auf die Ergründung der Hardware-Architektur/Technologie usw.

Selbst im Bereich der Grafikprogrammierung gibt es jedoch einiges zu lernen. Wenn man tatsächlich Spiele entwickeln möchte, so sollte man sich hiermit schon einige Jahre auseinander setzen. Auch hier gibt es jedes Jahr neue Paper zu neuen Entwicklungen, die Grundlagen sollten jedoch in 1-2 Jahren zu erlernen sein. Wohlgemerkt: Grundlagen != Effiziente Programmierung. Letzteres dauert dann doch ein paar Jährchen länger.

Im Gebiet der Hardware (weil es hier ja öfter angesprochen wurde) könnte man das Ganze von klein nach groß aufbauen. Also (wie es an vielen unis auch ist) etwa nach folgendem Schema:
- Elektrotechnische Grundlagen
- Aufbau von Gattern, Boolsche Logik, Cmos-Technologie
- Aufbau von simplen arithmetischen Einheiten (Carry-Look-Ahead Addierer, Muliplizierer, Multiplexer, FlipFlops usw)
- Rechnertechnologie (DRAM, SRAM, ... )
- Rechnerarchitektur (ISA, Pipelining, Superscalar/VLIW ... )

Dazu dann natürlich noch bei Interesse Dinge wie Entwurfstechniken und co. Das reicht vielleicht um eine erste Idee zu bekommen, mit was man es eigentlich zu tun hat und einem eine Basis gibt, um tatsächlich mal so etwas in VHDL nachzubauen.
Viele praxisrelevante Themen werden aber sicher auch in diesen Vorlesungen einfach außen vorgelassen. So stößt man schon, wenn man sich das erste Mal mit Kernel-Programmierung beschäftigt auf neue Themenkomplexe. Eine Betriebssystemveranstaltung kann hier vielleicht etwas mehr (highlevel-)Hintergrundwissen verschaffen, aber wie das genau abläuft erfordert dann schon etwas mehr Eigeninitiative (wobei lowlevel und OSDevelopment einem schon einiges abnehmen).

Also mit genügend Zeit kann man sich schon einiges an Wissen aneignen und weit kommen. Das kann dann aber auch nur der Startpunkt sein, um sich mit 1-2 Themen dann in der Tiefe zu beschäftigen.

@ SoDaTierchen
Ist das nicht einfach der fastcall-Standard? Zumindest ist das in C/C++ in der Regel auch so, wenn man nicht mit bestimmten Flags kompiliert. Das hat auch etwas damit zu tun, zu was die Hardware in der Lage ist.

Was BranchPrediction und Caches angeht kann man heute nicht mehr ganz so generelle Annahmen machen. Hier werden auch Vorhersagen darüber getroffen, welche Werte als nächstes in den Cache geladen werden müssen und bei SMT ist die BranchPrediction auch etwas weniger Interessant geworden.
Eine generelle Empfehlung sollte aber immer noch sein Lokalitäten so weit wie möglich zu fördern. Das ist natürlich einfacher gesagt, als getan ^^
 
Ich muss gestehen, dass ich mich mit Optimierungen in Richtung Hardware lediglich in c# und für SEHR einfache GPU-Shader befasst habe. Dass fastcall für alle (oder fast alle) Programmiersprachen gilt, ist mir nicht bekannt, einfach weil die Zeit fehlt sich für alle Programmiersprachen so im Detail zu begeistern^^ Ein kurzes Nachlesen ergab, dass es Compilerabhängig ist und Microsoft-Compiler wohl fastcall für 32 Bit als Standard setzen.

Bezüglich Branch Prediction würde ich dir uneingeschränkt zu stimmen. Sofern der Compiler was optimieren darf ist es "relativ" schwer, dahingehend zu optimieren. Wenn man aber eine Unmenge an Funktionen statisch deklariert und mit irgendwelchen Instanzen quer über den ganzen Quellcode hüpft anstatt zusammenhängende Code-Blöcke zu schreiben, wird sich das in der Laufzeit schon bemerkbar machen. Für die meisten Leute ist das einerlei, weil der RAM für viele schnell genug ist, aber wer den Anspruch hat "alles" zu lernen um effiziente Programme schreiben zu können, der sollte davon schon einmal gehört haben :)
 
SoDaTierchen schrieb:
Für die meisten Leute ist das einerlei, weil der RAM für viele schnell genug ist
Ich wollte hier eigentlich keine Diskussion lostreten, was denn nun für effiziente Programmierung am wichtigsten ist, aber der RAM ist für NIEMANDEN schnell genug. Nur als grobe Abschätzung:
In der Zeit, die es brauch um eine Cacheline aus dem RAM zu holen kann ein Haswell Prozessor theoretisch über tausend (SIMD) Fließkommaoperationen durchführen und selbst ohne Vektoreinheiten sind wir noch bei mehreren hundert Operationen.
Wenn überhaupt, dann ist der Cache groß genug, dass eine ineffiziente Nutzung nicht immer auffällt. Was im Cache landet kann man bei üblicher Desktop-SW zwar nicht direkt festlegen, aber man kann (und sollte) seinen Code so schreiben, dass Cachemisses minimiert werden.

Aus reiner Neugierde (Ich hab von effizienter C# Programmierung keine Ahnung): Ist das mit der Performanceeinbruch bei mehr als 4 Argumenten wirklich bemerkbar? Ich hätte erwartet, dass der Overhead eines Funktionsaufrufs in der Regel ohnehin so groß ist, dass ein paar zusätzlich load/stores - die ja direkt aus dem L1 (evtl. sogar storebuffer) bedient werden können - nicht groß ins Gewicht fallen. Sehr kurze Funktionen werden in nativen Sprachen ohnehin ge-inlined (ich weiß aber nicht, wie das bei C#/.net ist).
 
Zuletzt bearbeitet:
Ich habe mich etwas zu unklar ausgedrückt. Mit "einigen Leuten" habe ich eigentlich in die Richtung der Entwickler geschossen, die sich wirklich gar keine Gedanken über Performance machen. Was manchmal an Performance auf dem Markt landet ... Mikrooptimierung schön und gut, aber wenn die Komplexitätsklasse des Algorithmus schon nicht stimmt, dann spielt die RAM-Geschwindigkeit keine Rolle mehr. War eher sarkastisch denn ernst gemeint :)

Um deine Neugier zu befrieden: Ich habe noch keinen wirklichen Vorteil bemerkt. Ich programmiere aber generell recht optimiert, da fallen manche Schritte mehr, andere weniger ins Gewicht. Ich versuche einfach immer auf alles zu achten, wenn man dann doch mal was übersieht ist es idR. nicht dramatisch.
Aber ein wenig neugierig macht mich dein Nachfragen schon. Ich glaube, ich puzzle mir morgen mal ein kleines sample, was den Unterschied klarstellt. Ob man das dann wenigstens theoretisch bemerkt (oder sogar praktisch relevant ist) interessiert mich schon^^ Bisher hab ich nie hinterfragt ob das nötig ist, sondern einfach so drauf geachtet mich daran zu halten.
 
Den CPU-Cache kann man leider (oder zum Glück) nicht aktiv beeinflussen. Daher ist hier eher das Wissen, was im Cache landet, wichtig, als wie der Cache selber funktioniert.

Teilweise geht es schon z.B. mit Prefetching Instruktionen, locking Instruktionen, oder Scatchpad-Funktionalitäten/Instruktionen oder Speicherinstruktionen die am Cache vorbeigehen.
 
Auch wenns etwas OT ist: Hier gibts übrigens nen schönen Vortrag der ein paar Dinge anspricht, die für die effiziente Spieleprogrammierung (in bezug auf das SW Design) wichtig sind. Und der Vollständigkeit halber, gibts hier noch die wahrscheinlich berühmtestes SO frage zum Thema Branch Prediction.
 
Zurück
Oben