Wie viele Threads sollte man nutzen?
-
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.
-
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.
-
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.
-
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
-
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.
-
Zeitschlitzverwendung schrieb:
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.
Wenn ein Thread schläft, dann bedeutet das, dass dieser garnicht im Scheduling einbezogen wird bis seine Bedingung (condition) ein Signal bekommt. Also keine Sorge, der Thread kann technisch nichts bremsen.
Wenn du das ausprobieren willst, kannst du ein OpenMP Program erstellen, dann siehst du im Task Manager, dass dein Program mindestens soviele Threads hat wie deine CPU gleichzeitig verarbeiten kann, jedoch wird es nur ein Core/Thread deiner CPU auslasten wenn du keine OpenMP direktiven verwendest.
-
hustbaer schrieb:
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.
Es kommt doch drauf an, für was man das Designmittel "Thread"s einsetzt:
a) Entkoppelung
b) PerformancesteigerungIm Falle von Entkoppelung setzt man für Module, die man in ihrer Ausführungsreihenfolge unabhängig sind, unterschiedliche Threads ein. z.B. mache ich das oft um eine GUI vom eigentlichen Logik zu entkoppeln. Man möchte ja durchaus noch eine bedienbare GUI haben auch wenn man ansonsten komplizierte Berechnungen ausführt.
Im Falle von Performancesteigung verteilt man die "Arbeit" z.B. eine komplizierte Berechnung, auf mehrere Threads. Es sollte einleuchten, dass dafür mehr Threads als physikalische Kerne verhanden sind zu keiner weiteren Performancesteigerung führt. Damit das klappt, muss man seine Arbeit in "Jobs" aufteilen können, die man dann an die Threads verteilt.
Um mal aufs Spiel zurück zu kommen: Ich würde also die "AI" nicht auf einem extra dafür bestimmten Thread laufen lassen. Die AI ist nämlich etwas, was sowieso in der Gameloop bei jedem Durchlauf berechnet werden muss. Man könnte die Berechnung der AI also als Job sehen. Wenn man richtig viel AI zu berechnen hat (z.B. weil viele Gegner, man denke mal an die 1000sende Gegner und Player, die ein MMORPG Spieleserver betreuen muss), könnte man sogar den "AI Job" in weitere Subjobs aufteilen. Es gibt natürlich noch andere Jobs: Netzwerkcode, Animation, Positonsupdate, Collision-Detection, ...
Die Jobs kann man dann auf so viele Workerthreads verteilen, wie man Kerne hat und damit den Rechner optimal ausnutzen.
Damit habe ich wohl deutlich gemacht, dass ich ein Job-basiertes Design wählen würde; auch schon weil es in Zukunft eher Rechner mit mehr Kernen als höherer Taktrate geben wird.
-
Die Taktrate hat sowieso eine obere Grenze, zumindest bei unserem momentanen Forschungsstand. Gerade deswegen weichen die Prozessorhersteller auf Multicore aus.
Kann auch sein, dass ich mich irre...
-
Graphen.