Während eine Bibliothek wie SDL eine plattformübergreifende Wrapper-API für das Threading bereitstellt, wäre es meiner Meinung nach naiv anzunehmen, dass dies direkt zur einfachen Entwicklung von Spielen auf sehr unterschiedlichen Plattformen (Desktop / Mobile) führt.
Was ist der beste Weg, um die Entwicklung auf diese Weise anzugehen (unter Berücksichtigung einer plattformübergreifenden Threading-API), wenn Folgendes berücksichtigt wird:
- unterschiedliche Anzahl von Kernen
- Sehr unterschiedliche Verarbeitungsmöglichkeiten pro Kern
- Eine generell andere Systemarchitektur mit z. Unterschiedliche Latenzen für Cache, RAM und E / A-Zugriff
Ich habe das Gefühl, dass der einzige Weg, dies zu tun, darin besteht, zu bewerten, wie viele Threads pro Gerät ausgeführt werden können, das Sie unterstützen möchten, und herauszufinden, welcher der kleinste gemeinsame Nenner ist. Dies lässt mich jedoch immer noch im Dunkeln, was den gesamten verfügbaren Verarbeitungsdurchsatz angeht. Habe ich Recht, wenn ich davon ausgehe, dass der einzige Weg, dies effektiv zu tun, darin besteht, aktiv für das niedrigste mobile Gerät zu entwickeln, das ich während der gesamten Entwicklung unterstützen möchte? - dh der kleinste gemeinsame Nenner? Sollte dies ungefähr ausreichen? Oder steckt noch mehr dahinter?
BEARBEITEN: Könnten andere bitte weitere Erfahrungen dazu machen, da ich der Meinung bin, dass meine Frage noch nicht vollständig beantwortet wurde.
quelle
Antworten:
Sie sprechen von "Multithreading-Schwierigkeiten", aber über welche Schwierigkeiten sprechen Sie tatsächlich? In gewisser Weise zitieren Sie ein Phantomproblem, das möglicherweise gar nicht existiert. Die eigentliche Herausforderung stellen Sie sich selbst - wenn Sie absolut entschlossen sind, den letzten Tropfen der Energie aus einem Stück Hardware herauszuholen, bedeutet dies, dass Sie die Hardware optimal einsetzen, aber auch die Kluft zwischen den leistungsstärksten Maschinen vergrößern und der am wenigsten mächtige. Dies hat zur Folge, dass Sie, wenn Sie ein Spiel haben, das wirklich das Beste aus einer PS3 macht (zum Beispiel), es sowieso nicht auf einem billigen Mobiltelefon laufen lassen können, sodass Ihr Problem nicht mehr darin besteht, wie ich 1 Programm bekommen kann auf sehr unterschiedlicher Hardware arbeiten "wird aber" wie kann ich 1 Spielidee auf verschiedene Arten umsetzen, damit es auf unterschiedlich starker Hardware funktioniert ".
Einfache Entwicklung von Spielen - klar. Optimales Multithreading, nein. Aber Sie müssen nicht brauchen Multithreading - Spiele zu machen. Um Hochleistungsprodukte herzustellen, ist es sicherlich hilfreich. Aber viele großartige Spiele laufen in einem einzigen Thread.
Anstatt zu versuchen, Systeme Threads zuzuweisen, weisen Sie Threads Tasks zu. Weisen Sie jeder Aufgabe die Daten zu, die sie zum Ausführen benötigt, und führen Sie die Aufgaben auf der jeweils verfügbaren Hardware aus. Normalerweise haben Sie eine Art Thread-Pool, um die verschiedenen Kerne oder Prozessoren zu abstrahieren, und einen Task-Manager, der eine Reihe von Tasks enthält und diese an die verschiedenen Threads weitergibt, wenn der Thread signalisiert, dass er die vorherige Task beendet hat und beendet ist bereit für einen neuen. Hardware mit mehr Kernen erledigt die Aufgaben offensichtlich schneller und kann schneller gerendert werden. Die Spezialisierung dieses Systems auf ein optimales Arbeiten auf Systemen mit unterschiedlichen Merkmalen wird zu einem fortgeschrittenen Optimierungsproblem, kann jedoch auf bestimmten Heuristiken beruhen (z. B. einer Aufgabe, die nicht erfüllt ist).
Die Zerlegung von Spielfunktionen in einzelne Aufgaben ist jedoch eine recht komplexe Angelegenheit und oft nicht die Mühe wert, es sei denn, Sie sind sich sehr sicher, dass Sie die Leistung benötigen, und die meisten werden es nicht einmal versuchen.
Einige weitere Lektüre:
http://www.gamasutra.com/view/feature/1830/multithreaded_game_engine_.php - siehe Abschnitt 'Daten parallel'. Bei diesem Modell werden die Daten auf mehrere identische Tasks aufgeteilt und auf einzelne Threads verteilt.
http://software.intel.com/de-de/articles/designing-the-framework-of-a-parallel-game-engine/ - ziemlich dicht, beschreibt Dinge auf Betriebssystemebene und nicht auf Spielebene.
http://drdobbs.com/high-performance-computing/216500409 - nicht spielspezifisch, aber absolut relevant für die Aufteilung der Aufgaben.
http://www.itfgaming.com/news/tech-focus-crysis-2-and-the-future-of-cryengine-3 - Auf halbem Weg ist dieses Interview eine Anekdote darüber, wie sie auf ein aufgabenbasiertes System migriert sind .
quelle
Als ich Handyspiele gemacht habe, haben wir zuerst eine "goldene" Version (dh ein voll funktionsfähiges Spiel) entwickelt und dann in drei Hauptversionen (Großbild, Mittelbild und Kleinbild) aufgeteilt. Diese wurden weiter in 11 Versionen konvertiert: Anspruchsvolle Grafik (Lesen benötigt viel Speicher / CPU) im Vergleich zu Low Profile usw. (es gab auch einige spezielle Plattformversionen).
Das größte Problem war (das war unter anderem meine Aufgabe), die benötigten Plattformen zu isolieren und diese Versionen zu bestimmen und zu ermitteln, wie sie erstellt werden sollen (dh Großbild, aber Low Profile sollte eine herabgestufte Version von Großbild / Hi Profile sein oder sollte es sein) mittelgroßer Bildschirm / großes Bildschirmprofil?).
Natürlich haben wir dies so programmiert, dass Spiele sehr stark von der Bildschirmgröße abhängen.
HTH
[edit] Was ich meinte war, dass Sie Ihre Zielplattformen in verschiedene Qualitäten aufteilen müssen (dh 1 Kern, 2 Kerne, 1 Kern, aber doppelt so schnell ...). Dann entscheiden Sie, wie viele virtuelle Ziele Sie wollen (zum Beispiel " only one "oder" Low, Mid, Hi ") Dann platzieren Sie alle Plattformen in ihrer jeweiligen" Qualität "und nehmen für jede Qualität den niedrigsten Nenner und" portieren "den Code, damit er diesen Anforderungen entspricht (dh funktioniert und schnell ist genug).
Es mag den Anschein haben, dass Sie dies mit ziemlich viel Rätselraten tun müssen, aber Sie können bereits die schlechteste Qualität mit der schlechtesten Plattform finden. Ich würde jede nächste Qualität mindestens "doppelt so gut" wählen wie die erste, dies würde wahrscheinlich nicht mehr als 3-4 "Qualitäten" erzeugen. Wenn der Code von einer Gold-Version portiert ist, kann jede Plattform, die nicht gut genug funktioniert, auf eine niedrigere "Qualität" zurückgesetzt werden, um die Geschwindigkeit zu erhöhen. Jede neue Plattform könnte auch leicht in der richtigen Qualität platziert werden.
quelle
Nicht unbedingt - es besteht möglicherweise die Hoffnung auf eine dynamischere Lösung, dies hängt jedoch von dem tatsächlichen Problem ab, das Sie zu lösen versuchen (falls vorhanden). Ihre Frage ist etwas vage, daher muss meine Antwort auch vage sein.
Wenn die Gruppierung von Plattformen, auf denen Sie ausgeführt werden möchten, die Möglichkeit zur Hardware-Aufzählung über eine API bietet, können Sie über diese Schnittstelle die maximale Anzahl von Threads ermitteln, die das System verarbeiten kann, und auf dieser Grundlage festlegen, wie viele Threads Ihre Anwendung ausführen soll sollte schaffen. Die einzige Herausforderung besteht darin, diese APIs zu finden. Ob Sie zur Betriebssystemebene wechseln oder nach einer Drittanbieter-Bibliothek oder einem plattformübergreifenden SDK / API suchen, liegt bei Ihnen und hängt von den Plattformen ab, die Sie unterstützen möchten.
Meiner Meinung nach sollte keines dieser Dinge Ihr Anliegen sein. Ihr Anliegen sollte es sein, Ihr Spiel aufzubauen. Wenn Sie auf einen Engpass stoßen und entscheiden, dass es besser ist, einen separaten Thread für eine bestimmte prozessorintensive Aufgabe zu erstellen, erstellen Sie den Thread und lassen Sie das Betriebssystem und andere untergeordnete Software entscheiden, wie die Hardware für das Threading bearbeitet werden soll.
quelle