GPU Computing für Spiele?

Supercomputer

Experte
Thread Starter
Mitglied seit
16.10.2014
Beiträge
37
Guten Abend,

da ich nun seit diesem Semester Elektrotechnik / Informatik studiere,
ist meine Leidenschaft zum Programmieren wieder vollkommen entfacht.

Doch leider wird im Studium nicht sehr viel aktiv Programmiert, es gibt zwar die Übungen,
doch meine Kenntnisse überschreiten den aktuellen Stand bei weitem,
daher ist dies nicht wirklich befriedigend und ich suche mir nun eine fordernde Aufgabe,
an der ich mich in den nächsten Jahren gütlich tun kann.


Nun ist mir die Idee gekommen auf Parallelisierung zu gehen, sprich Multithreading und GPU Computing.
Das ganze in einem Projekt, damit ich ausgiebig: üben, scheitern, lernen und die neu erworbenen Kenntnisse vertiefen kann.

Die Idee, für ein solche Projekt wäre, eine Art "refresh" vom klassischen "Supreme Commander Forge Alliance" zu schreiben.
(Natürlich kein stumpfer Klon, sonder auch mit eigenen Ideen...)
Und so ein SC ähnliches Spiel auf den aktuellen Stand der Technik zu bringen, da SC bei einer gewissen Einheiten stärke sehr träge wird.
Geplant habe ich für dieses Projekt die Zeit neben dem Studium, also etwa 5 Jahre.
Die Sprache meiner Wahl ist C++, da ich mit dieser bereits mehr als drei Jahre Erfahrung habe.
Mir ist dabei durchaus bewusst, da 3 Jahre nicht ausreichen, um wirklich gut zu werden, doch ohne Herausforderungen kann man nicht wachsen.


Die Hauptfrage, die ich mir aktuell stelle ist, wie verhält es sich wenn ich die Einheiten nicht seriell über die CPU, sondern
parallel über die GPU berechnen lasse, da ich mir so gerade bei größeren Einheiten zahlen durch die massive Parallelisierung,
im Vergleich zum rechnen über die CPU starke Performancegewinne erhoffe.

Nun zum Grundlegenden:

Für die CPU habe ich folgende Threadeinteilung (theoretisch geplant), falls davon etwas sinnlos ist,
scheut euch nicht davor Verbesserungsvorschlägen zu kommentieren.

1. MainthreadSynchronisierung der Threads, speichern usw.
2. ThreadSocket, zur Kommunikation mit Mitspielern
3. ThreadNutzereingabe, um ein "freezen" der Oberfläche zu verhindern.
4. Thread Schnittstelle zur Grafikkarte, verschieben der Daten usw
GPUBerechnung der Truppen und Bildschirmausgabe.

Die Truppenzahl wird dann wie folgt theoretisch beschränkt werden:

  1. Wenn der Speicher der Boottleneck ist: Verwendbarer Speicher minus Speicher für die Grafikdarstellung,
    Verbleibender Speicher durch (Speicherbedarf pro Truppe mal Anzahl der Spieler)
    ergibt dann die maximal mögliche Truppenzahl,
    ohne massiv Daten aus dem Speicher verschieben zu müssen.
  2. Wenn die Rechenleistung der Boottleneck ist:
    Zeit pro berechneter Truppe mal erwünschter FPS Rate
    durch die zu Verfügung stehenden Rechenkerne.

Wie ihr merkt, noch alles sehr theoretisch, da ich bisher nur mit einem Thread gearbeitet habe.
Daher habe ich nun folgende Fragen, die hoffentlich alle beantwortet werden können.

Wie stark beansprucht es die Karte, wenn ich z.B. CUDA Kerne bis zum Anschlag belaste?
Können dann überhaupt noch die Berechnungen für die Bildschirmausgabe ausgeführt werden?
Oder Hocken die Rechenkerne in einer Pipe und blockieren so diese Möglichkeit,
der gleichzeitigen Berechnung und Ausgabe auf dem Bildschirm?

Sollte das der Fall sein, ist es dann Besser, zwar alle Berechnungen der Truppenbewegungen mit voller Kapazität,
jedoch abwechselnd zur Grafikberechnung aus zu führen, oder lieber nicht alle Truppenbewegungen gleichzeitig zu erledigen?
Sprich einen Teil der Grafikleistung für die Truppenberechnung, den andere für die Darstellung zu nutzen.

Dann stellt sich mir noch die Frage nach der API (CUDA, OpenCL, Vulkan o.ä.)
Ich vermute mal, dass CUDA auf NVidiakarten schneller als OpenCL und Vulkan auf AMDkarten schneller als OpenCL laufen wird, oder?
Macht es dann Sinn, während der Installation/Laufzeit zu prüfen,
welche Grafikkarte verbaut ist und dann den entsprechend optimierten Code zu nutzen?

Zur Bildausgabe werde ich auf OpenGL setzten, da ich hauptsächlich Linux nutze und dieses Spiel primär für diese Plattform entwickeln möchte.
Zumal der Socket unter Linux deutlich einfacher zu Coden ist, als unter Windows :haha:

Bitte jetzt nicht direkt damit ankommen, "Du hast keine Ahnung wie Komplex das Thema ist" o.ä., ja es ist eine Herausforderung,
mir ist klar, dass Heutzutage Teams mit einigen Mitbarteitern an solchen Aufgaben programmieren und mir ist auch klar,
dass das eine Menge an Zeit brauchen wird, bis ich etwas einiger maßen performantes auf die Beine gestellt bekomme.


Doch in meinen Augen, ist genau diese Herausforderung und das tiefer gehende Verständnis in diesem Bereich all dies Wert.
Auch wenn ich an meine Grenzen stoßen werde, so bin ich zuversichtlich diese überschreiten zu können, ohne an den Hürden zu scheitern.


Ich hoffe auf eine schöne Zeit, mit interessanten Diskussionen und einem unentwegtem Wissensaustausch.
Ups :eek:, der Post ist jetzt doch schon etwas länger geworden, als geplant :eek:
Ich bedanke mich dann bereits an dieser Stelle dafür, dass ihr euch all das durchgelesen habt.

Mit freundlichen Grüßen
Supercomputer
 
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Die Hauptfrage, die ich mir aktuell stelle ist, wie verhält es sich wenn ich die Einheiten nicht seriell über die CPU, sondern
parallel über die GPU berechnen lasse, da ich mir so gerade bei größeren Einheiten zahlen durch die massive Parallelisierung,
im Vergleich zum rechnen über die CPU starke Performancegewinne erhoffe.

Probier es aus... Aber ich behaupte mal ins blaue, die GPU wird wohl in vielen Fällen einfach ungeeignet sein, weil sie eben nicht alles kann. Bzw. vielleicht mit hinbiegen schon, aber das dann eben nicht schnell genug ist. GPUs haben (zumindest im klassischen AMD/NV Ansatz) Vorteile in einigen Szenarien, aber eben nicht in allen. Sprich einfach Code 1:1 von CPU auf GPU porten und meinen, das geht, ist nicht!
Anders schaut das möglicherweise bei Intels Xeon Phi aus, das ist x86 in sehr sehr breit. Leider aber auch recht teuer...

Für die CPU habe ich folgende Threadeinteilung (theoretisch geplant), falls davon etwas sinnlos ist,
scheut euch nicht davor Verbesserungsvorschlägen zu kommentieren.
Warum starr? Mach das, wenn überhaupt dynamisch... Sprich du arbeitest Multithreaded. Das heist, dein Workload läuft in Threads, die je nach Bedarf und Anforderungen eben angeschmissen werden.

(1)Wie stark beansprucht es die Karte, wenn ich z.B. CUDA Kerne bis zum Anschlag belaste?
(2)Können dann überhaupt noch die Berechnungen für die Bildschirmausgabe ausgeführt werden?
Oder Hocken die Rechenkerne in einer Pipe und blockieren so diese Möglichkeit,
der gleichzeitigen Berechnung und Ausgabe auf dem Bildschirm?

(3)Sollte das der Fall sein, ist es dann Besser, zwar alle Berechnungen der Truppenbewegungen mit voller Kapazität,
jedoch abwechselnd zur Grafikberechnung aus zu führen, oder lieber nicht alle Truppenbewegungen gleichzeitig zu erledigen?
Sprich einen Teil der Grafikleistung für die Truppenberechnung, den andere für die Darstellung zu nutzen.

(4)Dann stellt sich mir noch die Frage nach der API (CUDA, OpenCL, Vulkan o.ä.)
(5)Ich vermute mal, dass CUDA auf NVidiakarten schneller als OpenCL und Vulkan auf AMDkarten schneller als OpenCL laufen wird, oder?
(6)Macht es dann Sinn, während der Installation/Laufzeit zu prüfen,
welche Grafikkarte verbaut ist und dann den entsprechend optimierten Code zu nutzen?

(7)Zur Bildausgabe werde ich auf OpenGL setzten, da ich hauptsächlich Linux nutze und dieses Spiel primär für diese Plattform entwickeln möchte.

(1) Wenn Volllast, dann Volllast ;)
(2) Kommt drauf an... Siehe unten Punkt 4, das Problem ist hier eher bei NV im Moment zu suchen. Aber wie oben schon erwähnt, es gilt bei sowas doch in erster Linie erstmal zu prüfen, ob die GPU überhaupt für sowas taugt. Nur weil GPU drauf steht, muss das nicht zwangsweise auch in Schnell gehen.
(3) Wie gesagt, kommt drauf an... NV GPUs führen im aktuellen Stadium einen Kontext Switch aus, wenn du ihnen zur gleichen Zeit GPGPU und 3D Workload gibst. Wie schnell und ob das gut geht, steht auf einem anderen Blatt.
(4) Hier vermischt du etwas zu viel. CUDA ist für GPGPU, OpenCL ebenso. Vulcan ist Grafik, bspw. wie DX11, DX12 und Mantle (AMD only). Vulcan ist dabei quasi Mantle in neu bzw. basiert auf Mantle von AMD. Die Frage nach der API stellt sich aber in mehreren Richtungen... Denn zwischen dem Programmcode und der Bildausgabe liegt eine Schnittstelle. Diese wählst du, wenn du OpenGL willst, wirst du da mit Fußfesseln leben müssen. Sinnvoller wäre (heute) Vulcan, wenn es frei sein soll, oder DX12, wenn es MS only sein darf.
Maßgeblich zum Speed (und auch zur Abhängigkeit der CPU) trägt die API aber auch bei... Denn bis einschließlich DX11 bei MS und OpenGL 4.x?? (bin ich nicht so ganz sicher), hat es eben die Fußfesseln von vielen SingleThread Teilen IN der API. Das kannst du von außen nur bedingt umgehen. Es kommt also ggf. zu Limits, die du, parallel hin oder her auf der Gameseite, nicht umgehen wirst. Zumindest nicht ohne weiters. Bei Thema dabei ist aktuell (siehe diverse Newsmeldungen im Netz) das Thema DrawCall Limit. Diese Aufrufen müssen erfolgen und skalieren bis einschließlich DX11 und auch OpenGL irgendwas nicht mit der CPU Breite. Deckelst du dort an, wirds nicht schneller werden... Das umgehst du mit neueren APIs in dem Bereich (Vulcan, DX12)
Was du als GPGPU Backend nutzt, ist dabei erstmal losgelöst... CUDA bietet sich für NV sicher an, je nachdem, wie Flexibel es sein soll, bist du mit CUDA aber bei NV only und damit eben Herstellergebunden. OpenCL wäre ungebunden... -> und eher passend um Linux/freien Ansatz.
Was noch zu erwähnen ist/wäre, der Part mit GPGPU und 3D auf der GPU zur selben Zeit, hier gibt es im Moment Unterschiede zwischen AMD und NV... NV führt wie gesagt einen Kontextswitch aus, das geht mehr oder weniger schnell. AMD hingegen fährt einen anderen Weg, es kann GPGPU Workload während der 3D Berechnung eingeschoben werden und die GPU führt den Spaß dann mit freien Ressourcen bspw. aus. (um es vereinfacht auszudrücken)
(5) Nicht zwangsweise... Es kommt eher auf die Umsetzung und den Workload an. Brichst du es bis auf die einfachsten Teile runter, dürfte der Unterschied gegen Null gehen. Entscheidender ist aber, wie tut es im großen und ganzen? Wenn du mit CUDA Sachen machst, du du mit OpenCL bspw. nur umständlich/anders hinbekommst, wäre CUDA eher im Vorteil (oder eben andersrum gesehen im Nachteil)
(6) Wenn du dir den Aufwand machen willst, dann definitiv JA. Das ist dann aber wieder so ein Punkt Feintunig aus meiner Sicht. Das Ganze am Ende zu optimieren und Feinzutunen kannst Step 3 auf der Agenda, nach Plan/Konzeptionierung und Umsetzung.
(7) Wie gesagt, eher Vulcan wäre wohl ratsam!?

Bitte jetzt nicht direkt damit ankommen, "Du hast keine Ahnung wie Komplex das Thema ist" o.ä., ja es ist eine Herausforderung,
mir ist klar, dass Heutzutage Teams mit einigen Mitbarteitern an solchen Aufgaben programmieren und mir ist auch klar,
dass das eine Menge an Zeit brauchen wird, bis ich etwas einiger maßen performantes auf die Beine gestellt bekomme.

Neja, ich sehe sowas immer pragmatisch... Gut ist (ohne dir wirklich zu nahe treten zu wollen), du machst dir erstmal Gedanken. ABER und hier kommt der Punkt, andem das schon anfängt zu kranken, du musst dich erstmal mit der Spieleentwicklung beschäftigen. Das läuft nicht nur nach dem Motto, wir kloppen ein paar Zeilen Code und schon steht der Spaß. Ganz im Gegenteil... Bei stumpfer Programmierung für eine Kommandozeile brauchst du dir NULL Gedanken über die direkte Ausgabe machen. Bei Window based Tools kommt das schon oben drauf. Bei Games kommt zusätzlich noch der Part Grafik dazu. Du musst dich also mit 3D im generellen Beschäftigen. Sprich wie funktioniert da, was brauchst du mit Texturen, Faces, Beleuchtung, Schatten usw. usf.
Nimmt man es wieder pragmatisch, könntest du dich nun erstmal Jahre mit 3D und Animationen beschäftigen BEVOR du die erste Zeile Code einhämmerst. Eben um überhaupt erstmal zu verstehen, wie der Spaß in den Grundzügen funktioniert. Nicht umsonst sind meist die Programmierer losgelöst von den 3D Artists/Kontentdesignern.

Rein von der Basis her, du solltest dich entscheiden, ob du eine der frei verfügbaren Spieleengines nutzt oder selbst was auf die Beine stellst... Letzteres ist möglicherweise flexibler, für ein Ein-Mann-Projekt aber aus meiner Sicht der möglicherweise ungünstigere Weg. Mit der Wahl der Engine (oder der Entscheidung es selbst zu machen) kommt dann erst der Rest -> wie eben die Logik im Spiel. Im Moment wirkt es eher so, als machst du dir schon über Schritt 2 Gedanken, obwohl Schritt 1 gar nicht klar ist! Das kann so nicht aufgehen...
Ich würde also nicht sagen: "Du hast keine Ahnung wie Komplex das Thema ist", sondern eher, du fängst am falschen Ende an ;) Möglicherweise ist auch das selbstgesteckte Ziel zu hoch. Das lässt sich immer schwer beurteilen. Warum? Weil ich denke, du wirst in den ersten Monaten, vielleicht sogar Jahren keine wirklich greifbaren Erfolge damit erzielen. Baust du die Engine dann noch selbst, wirds noch ermüdender...
Aus meiner Sicht, wenn es dir primär um Parallelisierung geht, ich würde dort einen anderen Ansatz fahren, also weg von Games... Einfach weil Games noch viel mehr Fokus eben auf Optik und dergleichen legen als das reine Multithreading. :wink: Und ich denke, dir bringt es zumindest für den Anfang wenig bis nix, dich an der Engine oder dem Drum Rum eines Games zu verheizen, wenn dein Fokus wie du selbst sagst, auf Multithreading und ggf. GPGPU liegt...
Und wenn du es doch versuchen willst, dann wäre bspw. eine mehr oder weniger frei verfügbare Engine als Backend der sinnvollere Weg. Bspw. ist die Unreal Engine auf Github verfügbar... Kompilier dir den Spaß und schau, was das Dingens macht. Du kannst quasi frei dort Codezeilen ergänzen, hinzufügen usw. Es gibt Tonnen von Anleitungen wie man das macht, es gibt ne starke Community usw.


PS: ich kenne nun Supreme Commander nicht so detailiert, aber mal rein aus Interesse, um wie viele Einheiten reden wir denn überhaupt, andem der Spaß zäh wird??
So wie ich das sehe, der Game ist von 2007?? Mir scheint, von dem, was ich dazu laß, Probleme eher zu sein, dass A) die KI in EINEM Thread arbeitet und nicht in mehreren, bspw. pro KI einen (oder auch dort mehrere), B) viel Rechenzeit durch Simulationen drauf geht und C) möglicherweise die API limitiert (siehe DrawCall Thematik oben), vor allem obenraus mit mehreren Einheiten.
 
Da spinne ich mal mit :)

Mein erster Ansatz zur Truppenberechnung:

3D Matrize, welche quasi jeden Punkt auf der Karte mit jeder Einheit und jedem Einheitenzustand als Feld hat

Eine Einheit ist dann ein 3-dimensionaler Vektor, welcher eben genau auf das entsprechende Feld in der Matrize zeigt.

Die 3-dimensionale Matrize ist so aufgebaut, dass eine Interaktion zwischen zwei Einheiten den neuen Zustand für die Einheiten anzeigt, indem beide Vektoren miteinander verrechnet werden.

So, und die mathematische Beweisführung, ob so eine Matrize überhaupt existieren kann, überlass ich dir. Ebenso, wie diese zu konstruieren ist XD
 
Zunächst einmal ein herzliches Dank für die sehr ausführliche Antwort.
Ich habe nämlich tatsächlich nicht mehr mit einer gerechnet, um sie glücklicher bin ich, dass es eine solch ausführliche geworden ist.

PS: ich kenne nun Supreme Commander nicht so detailiert, aber mal rein aus Interesse, um wie viele Einheiten reden wir denn überhaupt, andem der Spaß zäh wird??
So wie ich das sehe, der Game ist von 2007?? Mir scheint, von dem, was ich dazu laß, Probleme eher zu sein, dass A) die KI in EINEM Thread arbeitet und nicht in mehreren, bspw. pro KI einen (oder auch dort mehrere), B) viel Rechenzeit durch Simulationen drauf geht und C) möglicherweise die API limitiert (siehe DrawCall Thematik oben), vor allem obenraus mit mehreren Einheiten.

Supreme Commander wird leider sehr schnell zäh, ab etwa 2k Einheiten auf dem Spielfeld, wird es merklich langsamer. Durch eine Mod, läuft es wenigstens ansatzweise auf zwei Threads, statt mit nur einem.
Dann schaue ich mir auf jeden Fall einmal Vulcan genauer an. Da ich auf der Linux Plattform zu hause bin, würde ich nur sehr ungern MS gebundene Techniken nutzen.

Das eine GPU kein Wunderwerkzeug ist, ist mir durchaus bewusst, doch für einfache Arithmetik sollte sie bei einer möglichst starken Parallelisierung schneller sein, auch wenn der Takt unter dem der CPU liegt.
Derzeit schlage ich mich mit OpenCL herum, mein derzeitige Grafikkarte ist wohl bereits zu alt, oder ich habe irgend einen anderen Fehler drin :$
Ich bin auf die Idee mit dem Spiel gekommen, da ich so auch direkt einen praktischen "nutzen" habe, ich weiß später was ich gemacht habe und kann, sofern es läuft, tatsächlich mit meinen Freunden Spaß haben und nicht nur eventuell physikalische Berechnungen durchführen.
Das mit der 3D Matrix ist auch eine gute Idee, ich hätte jetzt jeder einzelnen Einheit die Koordinaten direkt eingepflanzt und dann diese mittels Vektoren in die Bewegungsrichtung entsprechend verändert.

Mag sein, dass ich es von der "anderen" Seite her betrachtet habe, doch mir erschien es sinnvoller, zunächst in Erfahrung zu bringen, ob es überhaupt technisch umsetzbar ist, statt alles durch zu planen und dann fest zu stellen, es geht doch nicht.
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh