Wie viele Threads sollte man nutzen?



  • Ich erstelle gerade eine GameEngine (bin noch in der Planung) und frage mich was so das passende Anzahl an Threads ist, aus denen das Spiel besteht.
    Ich habe mir gedacht, ich nehme einen thread für grundlegende sachen wie das filesystem, einen für die game logik, auf die charactere, usw. zugreifen, einen für den player, welcher die kamera rendered und einen für die ganzen AI gesteuerten gegner.

    Was meine Frage dabei ist, gibt es irgentwelche Nachteile die auftreten, wenn ein Programm aus zu vielen threads besteht? (also abgesehen von wartezeiten von datensynchronisationen?

    PS: Sorry für die Rechtschreibung.. 😕



  • Komplexität. Du wirst garantiert fehler machen.

    Füge erst Threads ein, wenn du sie brauchst.



  • gamer8o4 schrieb:

    Ich erstelle gerade eine GameEngine (bin noch in der Planung)

    https://www.google.com/search?q=write+games+not+engines Das gilt umso stärker wenn du dich nicht für den tollsten Programmierer ever hälst, der viel schönere Interfaces designen kann als alle anderen.
    Zu deiner Frage: Warum lässt du das denn nicht den Clientcode entscheiden? Solange du alle Module schön enkoppelst und thread-safe hälst, sollte das kein Problem sein.
    PS: Für I/O: Die asynchrone OS API gilt eh als wesentlich performanter. 😉



  • https://www.google.com/search?q=write+games+not+engines Das gilt umso stärker wenn du dich nicht für den tollsten Programmierer ever hälst, der viel schönere Interfaces designen kann als alle anderen.

    Mein Ziel ist es nicht ein perfektes Spiel zu programmieren, sondern mein Wissen über GameEngine Architektur aufzubessern und nebenbei einige Entwurfsmodelle in C++ auzutesten. Mir ist klar das ich nie etwas schaffen werde wie Ogre3d, etc. dazu fehlt mir nicht nur das wissen, sondern auch die Mittel. Ich will halt eine GameEngine programmieren 😃 Ich hab mich jetzt auch längere Zeit vorbereitet indem ich einige Bücher über DX11 und allgemeine Themen in richtung game design gelesen habe.

    Warum lässt du das denn nicht den Clientcode entscheiden? Solange du alle Module schön enkoppelst und thread-safe hälst, sollte das kein Problem sein.

    hatte ich vor, aber damit kleine Spielchen oder Demos programmieren will, müsste ich trotzdem wissen, was der beste Weg ist 😉

    Komplexität. Du wirst garantiert fehler machen.

    Ein allgemeines Problem in der Programmierung von derartig Komplexen Sachen.
    Man verusucht es natürlich so einfach wie möglich zu halten, aber naja.. das klappt nicht immer und manchmal ist der komplexere der auf Dauer effizientere Weg.



  • Der effizienteste Weg ist erstmal so weit zu kommen, dass du an die Stolperstellen gerätst. Wenn du ordentlich programmierst, sollte Threading einfügen keine unglaublichen Umbaumaßnahmen erfordern. Was wichtig ist, dass du verstehst, wann, wo und wieso threading gebraucht wird. Wenn du nur kleine Spielchen programmierst, dann ist Threading overkill. Wenn du nie so viele ressourcen verwalten musst, dass du an die Grenzen des Rams kommst, dann tuts auch ein Ladebildschirm anstatt paallel nachzuladen. Wenn du nie so viele Objekte hast, dass deine Physik-Simulation/Grafik nennenswert Zeit verschlingt dann...du verstehst?

    Der Punkt ist, dass jede Komplexität die du jetzt hinzufügst verhinderst, dass du jemals an den Punkt kommst, sie zu brauchen.


  • Mod

    otze schrieb:

    ... Wenn du ordentlich programmierst, sollte Threading einfügen keine unglaublichen Umbaumaßnahmen erfordern...

    ich denke das ist leider oft nicht der fall.
    selbst wenn man ordentlich programmiert, erstellt man keine doublebuffer usw. und wenn man wirklich threading ausnutzen will, muss man es job basierend machen, nicht statisch threads fuer bereiche zuweisen und dann wird es schnell ein riesen refactoring, falls man noch zwischen den einzelnen jobs resource dependencies tracken will.

    fuer sowas wie einen raytracer geht es sicher einfach, da reicht sogar eine zeile openMP. wenn man schnell ein wenig boost haben will, kann man vielleicht auch bei einer game engine ein paar kritische loops beschleunigen, aber eine ganze engine die darauf basieren soll kann man im nachinein nicht umstellen ohne wirklich ein riesen refactoring. my2cent.



  • Was wichtig ist, dass du verstehst, wann, wo und wieso threading gebraucht wird. Wenn du nur kleine Spielchen programmierst, dann ist Threading overkill. Wenn du nie so viele ressourcen verwalten musst, dass du an die Grenzen des Rams kommst, dann tuts auch ein Ladebildschirm anstatt paallel nachzuladen. Wenn du nie so viele Objekte hast, dass deine Physik-Simulation/Grafik nennenswert Zeit verschlingt dann...du verstehst?

    darüber habe ich auch schon nachtgedacht, warscheinlich werde ich es erstmal nicht brauchen, aber ich will mir die möglichkeiten komplett offen halten und alles soweit wie nötig offen halten damit ich mir nichts verbaue.



  • otze schrieb:

    Komplexität. Du wirst garantiert fehler machen.

    Füge erst Threads ein, wenn du sie brauchst.

    Definiere "wann braucht man sie."

    <q>und einen für die ganzen AI gesteuerten gegner. </q>

    Wenn's für die KI viel zu berechnen gibt, dann würde ich für jeden NPC oder eine kleine Gruppe von NPCs jeweils einen Thread machen.

    Grund: Je mehr Cores eine CPU hat und je mehr Cores CPUs später bekommen, desto besser skaliert das Game.



  • Nachgehakt schrieb:

    Wenn's für die KI viel zu berechnen gibt, dann würde ich für jeden NPC oder eine kleine Gruppe von NPCs jeweils einen Thread machen.

    Grund: Je mehr Cores eine CPU hat und je mehr Cores CPUs später bekommen, desto besser skaliert das Game.

    Also bitte, so mit Threads um sich zu schmeißen ist der beste Weg das Programm drastisch zu verlangsamen.

    Zb mit einem Behaviour-Tree findet man doch so algorithmisch schnell eine Lösung, dass sich mehr als ein Kern dafür echt nicht lohnt.



  • Ich hab mal vor einer weile aus neugier geschaut, wie viele threads meine spiele haben. Bei starcraft2 waren es knapp über 40. und das spiel läuft schon ab 2.6 ghz dualcore...

    Wünsche euch ein frohes fest :xmas1:



  • Ethon schrieb:

    Nachgehakt schrieb:

    Wenn's für die KI viel zu berechnen gibt, dann würde ich für jeden NPC oder eine kleine Gruppe von NPCs jeweils einen Thread machen.

    Grund: Je mehr Cores eine CPU hat und je mehr Cores CPUs später bekommen, desto besser skaliert das Game.

    Also bitte, so mit Threads um sich zu schmeißen ist der beste Weg das Programm drastisch zu verlangsamen.

    Zb mit einem Behaviour-Tree findet man doch so algorithmisch schnell eine Lösung, dass sich mehr als ein Kern dafür echt nicht lohnt.

    Es kommt natürlich auf die Art des Spieles an, aber in einem typischen Single Player Egoshooter sind aus Performancegründen oft nicht mehr als 8 Gegner gleichzeitig sichtbar.
    Diese sichtbaren Gegner verwenden dann im Moment der Sichtbarkeit mehr und komplexere Algorithmen für die KI Berechnung, während die restlichen NPS auf der Karte entweder völlig inaktiv sind oder einem stark vereinfachten Algorithmus folgen.
    Dadurch ist das ganze gut in den Griff zu kriegen.



  • kralo9 schrieb:

    Ich hab mal vor einer weile aus neugier geschaut, wie viele threads meine spiele haben. Bei starcraft2 waren es knapp über 40. und das spiel läuft schon ab 2.6 ghz dualcore...

    Diese Beobachtung ist leider total uninteressant, so lange man nicht weiss was diese 40 Threads machen.
    Sogar calc.exe hat bei mir (Windows 8 x64) 3 Threads.


  • Mod

    viele threads werden aus faulheit und bequaemlichkeit erstellt, das hat weder was mit gutem design noch mit auslastung/optimierung zu tun. gibt leute die meinen fuer input einen thread haben zu muessen oder fuer sound mehrere oder fuer netzwerk.
    entsprechend gibt es auch libs die einige threads erstellen wenn man sie initialisiert, ohne dass es wirklich noetig ist.

    bei den 40 threads wuerde ich mir als nichts denken, kann gut sein dass ein video codec der 99% der zeit schlaeft sich einfach mal 8threads erstellt, nur damit diese nicht erst erstellt werden muessen wenn die erste cutscene kommt.



  • nun ja, starcraft 2 ist von blizzard und die würde ich nicht als unfähig beschreiben... :xmas1:



  • @kralo9
    Das hat nichts mit unfähig zu tun, manchmal ist es einfach praktisch.
    Speziell wenn man Libraries entwickelt kann es nötig sein bzw. die Dinge drastisch vereinfachen wenn man ein oder zwei Threads anlegt.
    Wenn man dann ein paar solche Libraries verwendet hat man gleich ein Dutzend oder mehr Threads.
    Ich sehe das nicht als Pfusch oder Designfehler oder sonstwas. Nur machen diese Threads trotzdem die meiste Zeit über nichts.

    Davon abgesehen sind gute Spiele von grossen Firmen nicht unbedingt ein Beispiel für tolles Softwaredesign. Die müssen nämlich auch irgendwann fertig werden, und nachdem diese Spiele nicht unbedingt lange gewartet werden müssen (im Vergleich zu Businessapplikationen) zahlt es sich auch gar nicht aus das ultimative Design zu haben.

    Und zuletzt: ein paar "unnötige" Threads zu verwenden mag zwar dem einen oder anderen "unsauber" erscheinen, ermöglicht aber oft ein wesentlich einfacheres Design -- daher würde ich es nicht grundsätzlich als schlecht bezeichnen. Ich verwende öfter mal Hilfsthreads die relativ wenig tun. Das System kommt gut damit klar, der Overhead ist quasi nicht messbar und sicher nicht spürbar -- wozu also eine kompliziertere Lösung implementieren?

    Soll heissen: ich bin mir sicher dass von den 40 Threads die Starcraft 2 verwendet die meisten den Grossteil der Zeit über einfach heia machen.


  • Mod

    kralo9 schrieb:

    nun ja, starcraft 2 ist von blizzard und die würde ich nicht als unfähig beschreiben... :xmas1:

    falls wir beiden die faehig als 'get shit done' und nicht als 'make code beautiful' ansehen, sind wir uns einig, sie sind faehig, sonst waere das spiel nicht raus, aber der code wunderschoen.



  • also ganz ehrlich, ich würde es bei dem ein oder anderen Spiel schon schätzen wenn die Macher mehr Threads verwenden würden. Ich denke da z.b an Skyrim. Beim Laden von neuen Mapteilen ging garnichts mehr, ausser dem Ton und das ist echt beschissen. Da merkt man garnichts mehr von "OpenWorld"

    Grundsätzlich würde ich den Ansatz einmal aus einer anderen Perspektive betrachten und mich da an dem Betriebssystem orientieren. Maximal so viele Threads wie CPU Kerne und dann geschedulte Jobs (nach priority, range oder what ever) in 1-n: n=anz Threads Queues


  • Mod

    einfach nur mehr threads erstellen macht nichts besser. ist wie einfach mehr raeder an einen wagen klatschen.

    das OS erstellt nicht soviele threads wie CPUs, an sich erstellt das OS (also der kernel) garkeine threads, sondern stellt die moeglichkeit zur verfuegung threads zu erstellen und jeder prozess bekommt erstmal einen und die meisten erstellen sich dann noch welche, gerade treiber.

    es per jobs zu machen waere schon gut, allerdings muss man das von anfang an als basis nehmen und die ganze engine etc. muss darauf aufgebaut sein, dann darf es keine "Sleep" geben wie die meisten thread-helden es machen und sofern es keine resourcen ausserhalb des job systems sind (z.b. device buffer), sollte die ownership vom job-system aufgeloest werden und keine locks/mutex/critical sections etc. dafuer verwendet werden.

    aber ich glaube sowas koennen die allerwenigsten aufsetzen, dazu braucht es viel erfahrung (und die bekommt man ja durch ein paar mal versuchen und bugfixen), dafuer hat man kaum die research zeit.



  • rapso schrieb:

    bei den 40 threads wuerde ich mir als nichts denken, kann gut sein dass ein video codec der 99% der zeit schlaeft sich einfach mal 8threads erstellt, nur damit diese nicht erst erstellt werden muessen wenn die erste cutscene kommt.

    Und damit bremst er dann das Spiel aus, wenn für diese 8 Threads, die nichts tun, 8 Zeitschlitze vom OS zugewiesen werden.



  • Pria schrieb:

    also ganz ehrlich, ich würde es bei dem ein oder anderen Spiel schon schätzen wenn die Macher mehr Threads verwenden würden. Ich denke da z.b an Skyrim. Beim Laden von neuen Mapteilen ging garnichts mehr, ausser dem Ton und das ist echt beschissen. Da merkt man garnichts mehr von "OpenWorld"

    So etwas passiert, wenn die Entwickler alle schon ne SSD Eingebaut haben und ungetestet bleibt, wie sich das Spiel auf Rechnern mit Festplatte verhält.

    Die SSD mag einen gewaltigen Peformanceschub gebracht haben, aber dies gilt nur für alte Anwendungen die auf Festplatten hin optimiert wurden.
    In Zukunft wird der Performanceschub einem einfacheren Softwaredesign zum Opfer Fallen und die Software auf Festplatten unbenutzbar werden.

    Das gleiche konnte man beim RAM Bedarf beobachten.
    Früher als RAM noch knapp war, wurde auf den Platzverbrauch hin optimiert, entsprechend schnell und effizient hat das Programm dann auch gearbeitet.

    Aber heute begnügt sich schon ein Browser mit 700 MB und mehr und ist trotzdem nicht schneller gestartet als früher zu Netscape 3.0 Zeiten.

    Dein angesprochenes Problem ist also keine Frage der Threads, sondern der Datenstruktur und Art und weise, wie die Daten auf die Festplatte gespeichert werden.


Anmelden zum Antworten