@Mindfucked
kleiner Hinweis, du solltest dich davon lösen, das ein Spiel Kerne unterstützt... Das tut es nämlich nicht.
Lies dir mal den folgenden, zugegebenermaßen sehr langen Text durch. Es ist ein einfaches Beispiel, wie das ganze abläuft...
Eine Anwendung (wie eben ein Spiel) ist entweder Multithreaded programmiert oder nicht.
Soweit erstmal die Grundlage. Ist es nicht Multithreaded programmiert, besteht absolut keine Möglichkeit, mit mehr wie einem Core auch mehr Performance zu bekommen. Bestenfalls noch, wenn man mit einem Dualcore sich dank zweitem Kern Luft für Hintergrundprozesse schafft, wäre ein kleiner Speedvorteil drin.
Bei einer Multithreadanwendung kommen nun aber ganz paar Probleme auf. Schau mal in deinen Taskmanager, dort steht beispielsweise wie viele Threads deine CPU aktuell händelt. Bei mir sind das aktuell 1259 Threads, die gleichzeitig laufen. Aufgeteilt auf 103 Prozesse, die gleichzeitig aktiv sind. Heist summa sumarum, ca. 12 Threads pro Anwendung laufen gleichzeitig.
Dennoch liegt meine Durchschnitts CPU Last im Desktopbetrieb irgendwo bei gerade mal <10% auf einem Quadcore + SMT Prozessor.
Wie man also wunderschön sieht, die Tatsache, das eine Anwendung mit mehr wie einem Thread umgehen kann, heist noch lange nicht, das es auch einen Speedvorteil bringt.
Um das mal bildlich darzustellen nutze ich gern das Thema Kaffee kochen, was wohl jeder kennt.
Folgende Arbeitsschritte sind nötig:
- Wasser in Kanne
- Wasser (aus Kanne) in Maschine
- Kanne unter Maschine
- Filter in Maschine
- Kaffee in Filter
- Brühen starten
Geht man der Einfachheit halber von aus, das jeder Arbeitsschritt genau gleich lange dauert ergibt sich genau die Reihenfolge, die ich beschrieb. Läuft das ganze sequenziel in einem einzigen Thread ab, gibt es logisch keine Optimierungsmöglichkeiten.
Programmiert man das nun Multithreaded, sogar so, das jeder Schritt in einem eigenen Thread läuft und nutzt genau einen Core (also eine Kaffeemaschine) wird sich an der Reihenfolge auch nix ändern, da immer nur ein Schritt zur selben Zeit gehandelt werden kann.
Was macht man also, um zu optimieren. Sofern Luft in Sachen Ressourcen vorhanden ist, wäre es beispielsweise denkbar die Schritte:
- "Wasser in Kanne" sowie "Filter in Maschine" und
- "Wasser in Maschine" sowie "Kaffee in Filter" zur gleichen Zeit auszuführen. Heist also, wir haben aus vier Zeiteinheiten nur noch zwei gemacht.
Nun kommt aber das Problem, mehr Optimierung ist nicht möglich. Da wir weder den Schritt "Kanne unter Maschine" zur gleichen Zeit mit einem der beiden anderen ausführen können (da die Kanne ja im zweiten Schritt zum befüllen der Maschine noch benutzt wird), noch den Schritt "Brühen starten" (der kann erst gestartet werden, wenn die Maschine alle Zutaten sowie Behälter hat)
Sofern man das halbwegs verinnerlicht, wird sich zweifelsfrei die Frage stellen, wie ist es möglich, bei zwei Cores aka zwei Maschinen eben die benanten beiden Schritte zur gleichen Zeit auszuführen? Da es ja rein logisch keinen Sinn ergibt, das "Wasser in Kanne" durch Maschine 1 sowie "Filter in Maschine" durch Maschine 2 durchführen zu lassen. (analog den nächsten zusammengefassten Schritt)
Und hier ist die Antwort, das Betriebssystem ist schuld. Denn das OS ist in der Lage, vereinfacht gesagt, Zustände bzw. Ergebnise oder Aufgaben von Core zu Core zu schubsen. Was soviel heist, wir können durch die zweite Maschine Schritte ausführen lassen und deren Ergebnisse können dann nach Beendigung 1:1 auch von Maschine 1 verwendet werden.
Unterm Strich ergibt sich also das Bild, das wir aus sechs Schritten genau vier machen könnten. Durch einen zweiten Core/eine zweite Maschine. Es ergibt sich also eine Zeiteinsparung der Arbeit von ziemlich genau einem drittel.
Ergo, die Ausführungsgeschwindigkeit steigt.
Weiter lässt sich dieses bildliche Beispiel aber nicht optimieren. Es besteht einzig die Möglichkeit, zwei Kaffee zur gleichen Zeit zu kochen. Sprich bei zwei Maschinen wäre ein Kaffee nach vier Zeiteinheiten bereit. Und zwei Kaffee aber schon nach sechs.
Das Problem von Spielen ist aber an der Stelle einfach die Tatsache, das viel zu viele Sachen sequenziel laufen müssen. Da es einfach viel zu viel dynamischen Kontent gibt, die im Vorfeld völlig unklar sind.
Um das nochmal am Beispiel zu zeigen, es ist unklar, wann die Kaffeemaschine Kaffee kochen soll. Heist also, es ist auch unsinn, im Vorfeld schon den Filter einzusetzen oder schonmal Wasser zu holen. Es könnte ja sein, jemand will nicht Kaffeesorte A sondern Kaffeesorte B. Und wenn dann Kaffeesorte B eine andere Flüssigkeit bzw. einen anderen Filter vorraussetzen würde, wäre die Arbeit nicht vorrausberechenbar.
Auch kommt erschwerend hinzu, das in Spielen idR die Berechnungen eben nur einmal ausgeführt werden. Heist also, ein Spiel verlangt nicht nach zwei Kaffee, sondern nur nach einem

Die zweite Maschine selbst bringt also maximal das 1/3 mehr Speed bei doppelten möglichen Ressourcen, wie im Beispiel.
Und geht man nunmal noch etwas weiter in die Materie, wird anders als im Beispiel nämlich idR die Tatsache eintreffen, das nicht jeder Arbeitsschritt auch immer gleich viel Zeit benötigt. Es wird wohl so sein, das der Schritt "Filter in Maschine" schneller geht, als der Schritt "Wasser in Kanne" bzw. "Wasser von Kanne in Maschine". Somit ergeben sich extrem komplexe Szenarien, die auch für die Entwickler von Software zum Teil einfach schlecht durchschaubar sind. Auch wenn potentiell viel Spielraum für Ablaufoptimierung vorhanden ist, wird so etwas in der Praxis gerade bei Games eher selten nachgepatcht.
Vergleicht man beispielsweise das Kaffeebeispiel in Form von Spielen mal mit einem Bild, was nach bearbeitung gerendert werden soll. So stehen ungleich des Spiels bei der Renderaufgabe beispielsweise alle Informationen im Vorfeld nahezu fest. Heist also, das Programm kann schauen, wie viele Maschinen habe ich zur Verfügung. Es weis, was am Ende bei rauskommen soll und kann dann die Arbeit schön in einzelne Teile zerstückeln. Jeder Teil arbeitet an einem eigenen Stück vom großen Kuchen und am Ende wird die Arbeit wieder zusammen gesetzt.
Bildlich könnte das zum Beispiel sein, das die Aufgabe wäre, 6l Kaffee zu kochen. Jede Maschine kann mit jeweils einer Kanne beispielsweise 500ml erzeugen. Bei 6 Maschinen ergeben sich also 12 Durchgänge, die nötig sind. Jede Maschine kocht somit zwei mal eine volle Kanne. Und am Ende wird alles in einen großen Eimer geschüttet und dem Anfragenden serviert
