Viel CPU-Cache hilfreich fürs Compilen? (Unity)

Periswoop

Komplett-PC-Käufer(in)
Ich arbeite aktuell an einem Spiel in der Unity-Engine und nach jedem Code-Change muss ich ca. ~15-20s warten bis es zum Testen ready ist. Diese Wartezeit würde ich gerne verkürzen.

Da meine CPU recht alt ist (Ryzen 5 1600X) wollte ich auf die Ryzen 9 7950X wechseln.
Mit der Ankündigung der Ryzen 9 7950X3D mit mehr Cache bin ich aber aktuell am überlegen noch ein wenig zu warten.
Kennt sich vielleicht jemand mit dieser Thematik aus, oder hat in die Richtung schon Erfahrungen machen können?

Ryzen 9 7950XRyzen 9 7950X3D
Basis-Takt4,50 GHz4,20 GHz
Turbo (1 Core)5,70 GHz5,70 GHz
Turbo (All Cores)5,20 GHz5,00 GHz
L3 Cache64 MB128 MB
 
Bei einem Ryzen 5 1600X wundert mich das überhaupt nicht. Da wäre ja selbst ein Ryzen 7 3700X schon mehr als doppelt so schnell. Benötigst du viele Kerne? Ansonsten würde ich mir mal den Ryzen 9 7900X anschauen. Viel Cache erhöht meines Wissens nach nicht die Anwendungsleistung.
 
Was haste denn für ein Board?
Wie Dave schon richtig schreibt, wäre ein 3700X ein massiver Zugewinn.
Wenn es das MB hergibt würde ich für super schmales Geld den 5900X draufklöppeln und 3-4 Jahre Spaß haben. So alt ist ja auch der 1600X :-)
Gruß T.
 
Kompilieren von Code skaliert in der Regel stark mit Threadanzahl (sofern unterstützt) und Takt aber kaum mit Cache.

Ich würde hier nicht die ganze Plattform teuer austauschen wollen weil das gegenüber einer viel günstigeren Option kaum Vorteile hat:
Kaufbeinen 5900X, update das Bios deines Boards, tausche (danach!) deine CPU durch den 5900X aus und du hast geschätzte 80% der Kompilierleistung eines brandneuen Zen4 Systems das ein Mehrfaches kostet verglichen mit einem einzelnen 5900er.
 
Benötigst du viele Kerne?
Es kommt häufiger vor das alle 6 Kerne (12 Threads) meiner jetzigen CPU voll ausgelastet sind. Also ja, viele Kerne :)

Was haste denn für ein Board?
Noch keines. Würde mir ein neues kaufen entsprechend der CPU. Soll aber definitiv AMD werden.

ein 3700X ein massiver Zugewinn
Schon, die ist aber ja auch schon 3 Jahre alt. Wollte schon was aktuelles haben.

Viel Cache erhöht meines Wissens nach nicht die Anwendungsleistung.
Das ist halt genau das Problem, ich verstehe wie der L3 Cache so grob funktioniert, quasi als Abkürzung zum RAM. Aber ich hab keine Ahnung warum das nun so ein großen Effekt bei Spielen hat. Jede andere Anwendung bei der die CPU die Daten bereits im L3 Cache findet, muss doch ähnliche Vorteile haben. Oder? Warum Spiele ja, Compilen nein?
 
Aber ich hab keine Ahnung warum das nun so ein großen Effekt bei Spielen hat.
Weil Spiele tendenziell erstens große Datenmengen gleichzeitig sofort verfügbar brauchen und zweitens viele zeitkritische Prozesse haben (denn erst wenn alles fertig ist kann ein Frame gerendert werden, wenn nur ein Detail fehlt muss alles warten).

Das bedeutet wenn viele wichtige Daten im (im Vergleich zum RAM) viel schnelleren L3 vorrätig sind hat das meist große positive Auswirkungen insbesondere auf die MINfps im CPU Limit.
Für übliche Anwendungen ist der Vorteil meist viel kleiner da hier nur selten voele Daten gleichzeitig verarbeitet werden sondern eher nacheinander und es auch seltener ist, dass alle Threads auf einen einzigen zwingend warten müssen (der, wenn er die benötigte Date nicht im L3 findet noch ewig auf den RAM warten muss - in so einem Fall macht praktisch die ganze CPU gar nix bis der RAM geliefert hat - im dem Bereich eine Ewigkeit). Sowas fällt beim kompilieren nicht auf da es dann halt 5,2 statt 5 Sekunden dauert - beim Spielen merkste einen kurzen Framedrop auf 10fps wo du sonst 70 hast aber sehr wohl...
 
Worauf sitzt denn dann Dein 1600X :what:
Hatte mich da glaub unverständlich ausgedrückt. Der alte Rechner soll erhalten bleiben. Hab stattdessen vor ein komplett neuen zusammenzustellen.

Danke für die Erklärungen @Incredible Alk! :daumen: Da bei einem Spiel die CPU ja auf einen einzelnen Frame jeweils hinarbeitet, hört sich das auch logisch an.

Na gut, dann nehm ich lieber die höheren Taktraten mit und verzichte auf die 3D-Cache Version.
 
Zuletzt bearbeitet:
Nachtrag 15.01.23:

Ich konnte den Ryzen 9 7950X jetzt eine Weile testen. Statt 15-20s benötigt Unity nach einem Code-Change nur noch 9s. Hab mir ehrlich gesagt weniger erhofft. Das reine Compilen scheint auch schnell zu gehen, zumindest sind kurzzeitig alle Kerne ausgelastet.
Screenshot 2023-01-15 114806.png


Ich denke da passiert davor und danach noch mehr was es bei Unity in die Länge zieht.
Generell ist Unity ja nicht gerade bekannt für seine Performance. Auch ein Grund warum viele zur Godot-Engine wechseln :-o
Mit der Brechstange, einfach viel gute Hardware einbauen, funktioniert für mich Unity dann aber doch.
Dauerte es sonst auch immer eine Weile nachdem ich den Play-Button gedrückt habe, ist das Spiel jetzt instant ready.
 
Zuletzt bearbeitet:
Aber Unity ist nicht perse schlecht in der Performance.
Da hast du recht!
Aber nur damit wir nicht aneinander vorbei reden, ich meinte den Unity Editor. Der ist halt eben sehr "heavy" weil er eben schon von Haus aus viel mitbringt, aber was ihn auch sehr langsam in der Handhabung macht.
Für jemand der ein kleines Spiel machen will und vllt nur ein älteren PC oder Notebook hat, schaut sich dann eben oft nach leichtgewichtigeren Alternativen um.
 
Ich arbeite aktuell an einem Spiel in der Unity-Engine und nach jedem Code-Change muss ich ca. ~15-20s warten bis es zum Testen ready ist. Diese Wartezeit würde ich gerne verkürzen.
Hey :)

Danke für den Hinweis in meinem Thread. Das mit der Compile-Time kann leider wirklich stören. Ich nutze jetzt einen M1 Max und hänge auch kurz im Recompile (schon beim Speichern), ist allerdings deutlich besser als mit dem letzten MacBook Intel Modell (2019). Es gibt verschiedene Ansätze, das Problem etwas besser in den Griff zu bekommen.

1) Auto Refresh disablen, das findet man unter Unity-Einstellung -> Asset Pipeline -> Auto Refresh (nicht zu verwechseln mit General -> Script Changes While Playing); ist per default enabled. Bei jedem Speichern (weil im Hintergrund der import stattfindet) wird Unity anfangen zu compilen. Wird das ausgestellt, gibt es keinen Refresh mehr. Dann muss man allerdings in Unity den Asset Refresh (Windows: CTRL+R) manuell auslösen (oder etwas scripten).

Vorteil: man kontrolliert selbst, wann compiled wird.
Nachteil: wenn man nicht dran denkt ist man kurz verwundert :)

2) Etwas mehr Aufwand aber eine sauberere Trennung von Unity-Editor und Code wäre der Weg über eine DLL. D.h. Du arbeitest quasi in Deiner IDE am Code, compilierst dort und lädst nur das fertige Ergebnis der DLL zu Unity. Wird in grösseren Projekten häufig so gemacht.

Vorteil: beide Systeme (Unity, IDE) tun, was sie am besten können (was bei Unity eben nicht compilen ist)
Nachteil: anderer Workflow, etwas mehr initiale Einrichtungsarbeit


(!) Wenn Du Code-Changes sofort testen möchtest, bleibt aber quasi hauptsächlich die zweite über. Wenn es Dich nur stört, dass Unity zwischenzeitlich compiled, dann kann man auch mit der ersten Varianten glücklich werden.


Nachtrag:
Viele Kerne / Threads helfen bei Unity vor allem an einer Stelle: kompilieren der Shader beim Export (wenn Du auf HDRP oder URP Pipeline bist). Das nimmt schon mal ordentlich Zeit in Anspruch, aber auch schnelle CPUs mit vielen Kernen werden bei (bei mir ~5 Compile-Schritte bei ~1200 Shadern) noch ein paar Minuten laufen :)
 
Hey Praagor, danke für deine ausführlichen Tipps!
Der Auto Refresh an sich stört mich nicht, nur die Dauer bis ich meine Änderungen mal im Editor testen kann. Was ja durchaus häufiger vorkommen kann (z.B. mal kurz Movement mit anderen Parameter testen, oder neue Codezeile etc.)
Der Tipp, das man die IDE den Code in eine DLL compilen lässt, ist mir tatsächlich neu. Das könnt ich mal probieren. Nur vermute ich mal das bei Änderungen der DLL, Unity weiterhin sich Zeit nehmen wird bis ich mal "endlich ran darf".
1674301637151.png


Ich hab noch in den Unity Foren gelesen, dass es auch helfen soll bestimmten Code den man eh nicht mehr anfässt, in DLLs zu packen, damit der nicht mehr neu compiled werden muss.
Oder bei Parametern, die einfach via public nach aussen in ein GameObject zu reichen und dort dann ändern -was dann nicht als Code-Änderung gilt.
 
Die DLL würde über die IDE compiliert, Unity würde beim Refresh nicht mehr compilen, aber natürlich die API/Header-Informationen auslesen (geht aber fix).

Wenn es nur um Parameter geht, die Du setzt, dann sollte das eh alles über die UI im MonoBehavior nach aussen gereicht werden.

In der Form
[SerializeField] private float movementSpeed = 5f;

Durch das SerializeField wird der Parameter public in der IDE zu setzen, aber nicht public zum ändern durch Scripte.
 
Wie siehts denn mit der restlichen Hardwareauslastung so aus? Speicheroptimierung könnte auch helfen, zum Beispiel indem du auf einer RAM-Disk arbeitest oder dir einfach eine schnellere PCIe SSD gönnst.
(Ich gehe mal davon aus dass du schon geschaut hast ob du genug Arbeitsspeicher hast)
 
Durch das SerializeField wird der Parameter public in der IDE zu setzen, aber nicht public zum ändern durch Scripte.
Danke für die Richtigstellung! Wusste tatsächlich garnicht das man damit auch private fields nach aussen hin sichtbar machen kann :daumen:

Wie siehts denn mit der restlichen Hardwareauslastung so aus? Speicheroptimierung könnte auch helfen, zum Beispiel indem du auf einer RAM-Disk arbeitest oder dir einfach eine schnellere PCIe SSD gönnst.
(Ich gehe mal davon aus dass du schon geschaut hast ob du genug Arbeitsspeicher hast)
Also im Taskmanager geht während dieser Zeit nix sichtbar hoch, bis auf die CPU (siehe Bild oben). Rechner ist auch neu, siehe mein Profil, mit 64 GB DDR5-6000 und NVMe:
y.png


Die Idee mit der RAM-Disk fand ich interessant und habs gleich mal ausprobiert. 20 GB Partition erstellt und das Unity Projekt (14 GB) drauf kopiert. Dabei davor und danach jeweils 3 Testläufe mit jeweils neu-geöffnetem Unity via Stoppuhr gemessen, nach einer Code-Änderung.

14 GB Unity-Projekt auf NVMe :
  • 13.19s
  • 11.17s
  • 11.82s
14 GB Unity-Projekt auf RAM-Disk:
  • 13.98s
  • 13.65s
  • 13.71s
Ich war doch etwas verwundert das da wirklich keine Besserung sichtbar ist, sogar ehr langsamer geworden.
 
Gut, die SSD ist ja schon ziemlich schnell.

Dass die RAM-Disk keinen Unterschied macht wundert mich trotzdem, die sollte mit 48GB/s entgegen der 7GB/s der SSD und niedrigeren Latenzen schon noch mal spürbar schneller sein.

Das Problem scheint hier der interne Compiler von Unity zu sein, ich finde dazu diverse Beiträge online. Es scheint auch ein paar Projekte mit dynamischer Compilierung zu geben, kann dir das vielleicht helfen?
 
Das Problem scheint hier der interne Compiler von Unity zu sein, ich finde dazu diverse Beiträge online. Es scheint auch ein paar Projekte mit dynamischer Compilierung zu geben, kann dir das vielleicht helfen?
Japp dazu gibt es auch riesige Foren Threads :haha: Das Team um Unity weiß auch um die Problematik und sie haben auch ne Initiative gestartet um diese Zeit runterzudrücken. Vllt ist es mit den neueren Unity Versionen auch schon besser geworden, bin aktuell noch auf 2021.3.

Hab halt dennoch gehofft das man es irgendwie mit Hardware bekämpfen kann. Es ist ja auch insgesamt besser geworden, nur eben nicht so stark wie ich erhofft habe.

Dieses dynam. Compilieren werd ich mir mal anschauen, danke für den Tipp :daumen:
 
Nun, wie mein alter Professor für Datenstrukturen und Algorithmen schon sagte: "Der bessere Algorithmus schlägt immer die bessere Hardware".

Du bist schon ziemlich gut ausgestattet was die Hardware angeht, weitere große Sprünge wirst du da nur noch machen wenn du deine IDE in die Cloud legst oder so. Das wird dann aber mit Sicherheit zu teuer.

Ansonsten lese ich hier einige Tipps über Assembly Definition Files. Ich kenne mich leider selbst nicht mit Unity und C# Entwicklung aus, aber vielleicht kannst du da noch ein paar Sachen optimieren.

Ansonsten musst du wohl hoffen dass Unity Technologies sich was schlaues einfallen lässt wie sie ihren Compiler beschleunigen.
 
Zurück