Profiling

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Jonathan
Establishment
Beiträge: 2602
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Profiling

Beitrag von Jonathan »

Moin,

in der Regel versuche ich ok-en Code zu schreiben und halte mich ansonsten an "erst schauen, ob man wirklich optimieren muss, bevor man damit anfängt". Aber wie es mir scheint, ist das jetzt so langsam eingetreten. Also wechseln wir zum nächsten guten Prinzip rüber, "erst messen, dann optimieren".

Nur wie? Tools finden sich, aber habt ihr Erfahrung damit oder persönliche Empfehlungen?

Ich verwende Windows, Visual Studio, C++, CMake und OpenGL. Aktuell geht es mir um Ladezeiten, da scheinen hauptsächlich die CPU und vlt. Festplatte involviert zu sein. Renderzeiten könnte ich mir ansich auch anschauen, ich vermute, dass da dann der Markt eher dünner ist, und man vermutlich einfach nSight verwenden würde? Aber welchen Profiler für den Rest, und was gibt es sonst noch so gutes zu beachten?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Krishty
Establishment
Beiträge: 8339
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Profiling

Beitrag von Krishty »

Ich kann ja zwei Erfahrungen listen, auch wenn’s schlechte sind

VerySleepy ist total abgespeckt. Eigentlich wäre das gut, aber hier bedeutet es: Keine Unterstützung für UTF-8 in Quelldateien. Keine Flame Graphs. Probleme, alle Debug-Symbole zu finden. Null Bedienkomfort. Ich nutze ihn manchmal, wenn ich keine andere Möglichkeit habe, und erinnere mich dann, es nie wieder zu tun.

Visual Studio unterstützt CPU, GPU (bisher nie benutzt) und funktioniert überraschend gut. Es gibt Flame Graphs, Caller/Callee-Graphen, usw usf.
Mich stört aber, dass er lustigerweise nicht voll integriert ist – er zeigt dir Quelltext an, aber das ist kein Visual C++-Quelltextfenster, also kannst du den nicht wie gewohnt editieren. Musst dafür Datei und Zeile erstmal über den normalen Solution Explorer wiederfinden (und hast dann nicht mehr die Timing-Informationen).
Die Installation ist extrem metastasierend und schlecht fürs System. Der Visual Studio Debugger basiert komplett auf Edge – wenn du das mal deinstallierst, kriegst du ihn nie wieder ans laufen.
Profiling-Sessions fahren alle deine externen Festplatten hoch (gibt dazu mindestens fünf Tickets, alle “Closed – Not Prioritized”). Die Edge-basierte Debugger-GUI verbraucht an sich schon so viel CPU und Arbeitsspeicher wie ein Computerspiel.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 5125
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Profiling

Beitrag von Schrompf »

Ich hab früher VerySleepy benutzt, aber das Ding ist echt rudimentär, es nützt Dir nur was bei wirklich hardcore CPU-lastigen WorkingSets. IO und Freunde kriegst Du damit nicht abgebildet. Und da jede höhere VisualStudio-Version jetzt nen Sampling Profiler eingebaut hat, gibt's auch nicht mehr wirklich Gründe, den einzusetzen.

Der VS-eigene Profiler taugt durchaus, aber für die selben Szenarien: hardcore CPU-only kriegst Du damit gut abgebildet.

Für IO kenn ich nix Hilfreiches, um ehrlich zu sein. Wenn ich den Verdacht auf IO-bound habe, pack ich mir nen kleinen Profiler-Helfer da rein: irgendwas, was im Konstruktor die Zeit misst und im Destruktor loggt, wie lange es gedauert hat. Oder nicht loggt, sondern auf irgendne Statistik einzahlt - kannst Du Dir dann ausssuchen. Aber das ist das Einzige. Auch wenn Du nen Verdacht hast, dass irgendein Mutex lange braucht, eh er das Lock bekommt, bist Du mit klassischen Profilern verloren. Die sampeln ja nur, und schlafende Threads, die auf ein Reschedule warten, tauchen da nicht auf.

Der Intel VTune kann das alles, aber der ist SACKTEUER. Und in der kostenlosen Version - wie in der Branche heutzutage üblich mit Zwangs-Account, Upselling-Nerv und künstlichen Einschränkungen - kriegst Du die einzelnen Threads nicht auf ner Timeline abgebildet, soweit ich weiß.

Wenn ich mal groß bin, schreib ich mit irgendnem kleinen GUI-Framework (nicht QT) einen Profiler, der mir zoombar Events verketten kann, dann kann ich mit plumpem Logging mein Job-System profilen.

Und für GPU-Load wie zum Beispiel "Warum bricht meine Framerate in dieser Ecke ein" ist NSight kaum zu toppen. Für mich nutzlos, weil ich noch DX9 nutze und niemand auf diesem Planeten sonst noch, aber ihr werdet diese Probleme nicht haben. RenderDoc ist ne super Alternative für Frame Debugging wie "warum seh ich mein Dreieck nicht", aber soweit ich weiß, kann der kein DrawCall-Timing. Was die AMD-Alternative taugt, kann ich nicht sagen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8339
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Profiling

Beitrag von Krishty »

Schrompf hat geschrieben: 08.02.2025, 23:24Für mich nutzlos, weil ich noch DX9 nutze und niemand auf diesem Planeten sonst noch
🙋‍♂️
Ich habe letztes Wochenende versucht, auf D3D9 Ex umzusatteln, aber irgendwas klappt nicht und ohne Debug-Runtime finde ich nicht raus, was.

Ich wollte auch immer mal RADs Telemetry testen. Ist auf Spiele optimiert. Wenn ich mal groß genug bin, nach dem Preis zu fragen …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
NytroX
Establishment
Beiträge: 398
Registriert: 03.10.2003, 12:47

Re: Profiling

Beitrag von NytroX »

Also für mich kommt es stark darauf an, was ich profilen möchte.
Ich gebe mal 3 Beispiele:

1) "Ich habe einen Call-Graph und will wissen wo zur Hölle die ganze Zeit verloren geht"
In dem Fall greife ich auf einen Sampling-Profiler zurück, also der schaut im Zeitraum x auf den Stack und berechnet dann statistisch in welcher Funktion wieviel Zeit flöten geht. Das funktioniert bei länger laufenden Funktionen ganz gut, aber in einigen Fällen auch nicht so.
Meist mache ich das mit Go, der Compiler kann das out-of-the-Box, aber andere Tools können das pprof-Format auch schreiben.
pprof kann da ein schönes GraphViz Bild erzeugen, da behält man ganz gut die Übersicht.
Habe ich gute Erfahrungen mit gemacht.

2) "Ich bin grad am optimieren und will ungefähr wissen, was bei den Maschinenbefehlen am Ende rauskommt"
Dazu gibt es Tools, die Analysieren wie lange eine Ausführung der Befehle auf einer echten CPU so dauern würden.
Das ist ganz nett, wenn man am Ausprobieren der Alternativen ist, also wenn man schon weiß das man was optimieren will (und wo).
Da hilft natürlich der Compiler Explorer (https://godbolt.org) und Tools wie llvm-mca. Das kann man auch im CompilerExplorer als Tool hinzufügen, das ist nett.

3) "Ich will genau wissen, was los ist"
Dann benutze ich Instrumentation, d.h. ich ändere das Programm und schreibe Messpunkte.
Das mache ich einfach in einem Custom Format und pre-allocate den Speicher, damit das Schreiben der Messung möglichst wenig Impact auf die Laufzeit hat. Am Ende des Programms schreibe ich das ganze als JSON in eine Datei und schaue sie dann mit Chromium oder einem darauf basierenden Browser an. (chrome://tracing in die URL, und los gehts)
Das funktioniert unfassbar gut!
Format für die Datei gibts hier: https://docs.google.com/document/d/1CvA ... r4qxyxotyw
Einfach ein paar Lanes mit Duration schreiben und los gehts. Das ist echt nice, weil man genaue Kontrolle darüber hat, was man sehen will und wie es im Chrome/Trace aussehen soll, und eine nette GUI bekommt man mit Chrome einfach so.


Für GPU ist für mich RenderDoc immer noch das non-plus-ultra, aber man braucht eine moderne API, also mit DX9 oder so ist man raus.
Vulkan geht gut, das nutze ich meist.
Benutzeravatar
kimmi
Moderator
Beiträge: 1412
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: Profiling

Beitrag von kimmi »

Aufgrund der etwas ernüchtenden Tools habe ich neben Visual-Studio mittlerweile einen einfachen Timer, der auch die entsprechenden Calls zählt, im Einsatz. Das benutze ich auch beim Profilen von Micro-Controllern.

VG Kim
Benutzeravatar
Schrompf
Moderator
Beiträge: 5125
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Profiling

Beitrag von Schrompf »

Danke für den Link zum JSON-Tracer-Format. Damit hab ich mein größtes Problem - eine sinnvolle Anzeige von Event-Daten - gelöst und muss nur noch die Messpunkte rausballern. Ja geil, hab ich Bock drauf!
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Matthias Gubisch
Establishment
Beiträge: 499
Registriert: 01.03.2009, 19:09

Re: Profiling

Beitrag von Matthias Gubisch »

Ich nutze in der Regel für so Dinge wie Startup den Visual Studio Profiler, zu dem wurde ja schon genügend geschrieben.

Für CPU seitiges Frame Profiling nutze ich Tracy, da ist zwar mit Instrumentierung aber sehr mächtig (theoretisch kann der auch GPU, das hat bei mir aber mehr schlecht als recht geklappt)

Für GPU Profiling nutze ich Nsight für NVidia und die Renderdoc Integration des AMD Tools (dessen Name mir gerade entfallen ist)

Ich wollte schon immer mal nsight Systems probieren, bin aber nie dazu gekommen.

Ausserdem habe ich ein paar selbstgebaute timer Klassen, die sind aber mehr dazu da um zu sehen ob etwas aus dem Ruder läuft, für die genaue Analyse dann eben die oben genannten Tools
Bevor man den Kopf schüttelt, sollte man sich vergewissern einen zu haben
Benutzeravatar
Jonathan
Establishment
Beiträge: 2602
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Profiling

Beitrag von Jonathan »

Vielen Danks fürs Feedback.

Ich will einerseits prinzipiell ein wenig mehr über Profiling lernen, aber andererseits war aktuell konkret der Fokus auf den Ladezeiten. Speziell vom Landvogt, da werden aktuell einfach alle Gebäude am Anfang geladen, und das beinhaltet Meshes, Texturen und Sounds.

Texturen werden derzeit schon parallel geladen (und bis sie geladen werden werden mini proxy-texturen mit der Durchschnittsfarbe verwendet, die dann zur Laufzeit ausgetauscht werden. Das System läuft schon eine Weile lang und ich bin ziemlich happy damit), Meshs werden anfänglich durch Assimp importiert, dann aber als Binärplob rausgeschrieben - d.h. eine Handvoll Vektoren mit Vertexdaten die direkt am Stück geladen werden können.

Aktuell scheint mir das Problem hauptsächlich bei den Sounds zu liegen. An den Ladezeiten kann ich wenig machen, ich will eigentlich nicht das Backend austauschen (ist aktuell SoLoud - was nicht toll, aber ziemlich ok ist), aber ich kann vieles gewiss auch in einen zweiten Thread auslagern und eine Priority-Queue zum laden verwenden. Die 5 Musikstücke (20 Minuten oder so) müssen einfach nicht beim Start schon von Ogg-Vorbis komplett dekodiert werden, man braucht ja für die ersten paar Minuten bloß 1. Für Sounds weiß ich noch keine Fallback-Strategie analog zu "statt Textur erstmal nur einfarbig), aber da viele Sound nur ambient sind, braucht man die auch erstmal nicht.

Vermutlich baue ich einfach ein System, wo noch nicht geladene Sounds einfach nicht abgespielt werden. Ein fehlgeschlagener Abspielaufruf könnte aber deren Priorität in der Warteschlange erhöhen. Da muss ich mich mal ransetzen und mir etwas gutes überlegen.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Schrompf
Moderator
Beiträge: 5125
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Profiling

Beitrag von Schrompf »

Von wieviel Sound-Ladezeit reden wir denn hier? Splatter war mit all seinen Sounds immer im Millisekundenbereich.Wir haben einen Strauß Sounds vorgecached, den Rest on-demand geladen und voll decoded, und Sprache/Musik aus dem Ogg gestreamed. Und man hat beim Spielen von all dem nie was gemerkt. Sprich: die Sounds waren beim ersten Mal halt 20ms später, das hat nie jemand gemerkt. Daher klingt es schon ein bissl seltsam.

Aber *das* sollte in nem Sampling Profiler sichtbar werden. Nur echtes IO würde da nicht auftauchen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2602
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Profiling

Beitrag von Jonathan »

Hmm, ja, muss nochmal im Detail reinschauen, ist das erste mal, dass ich diese "Flame Graphs" lese.

So sieht das Ding aus:
2025-02-13_13-01-13_devenv.png
Meine Analyse: Ganz oben "Landvogt", klar. Dann irgendeine Windows-DLL, kein Plan warum, aber wird schon passen? Dann kommen zwei Threads, rechts der Hauptthread, links der Texture-Loader. Letzterer dudelt fast ausschließlich in FreeImage (Datei von Festplatte in Hauptspeicher entpacken) und OpenGL (Texturen auf GPU schaufeln) rum - passt schon.
Der Hauptthread macht ein bisschen Kram, erst wird City initialisiert (rechts), dann das Savegame geladen (links). City macht viel im SoundManager, das ist wohl das Sounds-Laden. Das einzig nennenswerte außer Sounds ist ganz rechts klein das Kästchen - das ist GUI Laden, was wiederum Hauptsächlich Sprites sind (denn die sind wichtig und verwenden nicht den Texture-Lade-Thread für Lazy-Loading).
Savegame-Laden wiederum dödelt lange in "UpdateLoadingThread" rum. Das muss ich mir nochmal anschauen, der soll während dem Laden den Status regelmäßig aktualisieren und wartet auf den Mutex, wegen parallelem OpenGL Zugriff. Vielleicht ist das Quatsch und ich kann hier Wartezeit sparen. Ansonsten sind große Blöcke das Laden der Heightmap (wieder eine große Textur, und Bullet-Physics Collision Model erstellen), und die Material-Map (welcher Bodenbelag wo ist, also auch wieder eine Textur).

Das Viertel ganz rechts ist ja angeblich irgendetwas in der ntdll, da sehe ich keinen Code zu und hab keine Ahnung was da so lange dauert.

Was ist also jetzt das Optimierungspotential? Hauptsächlich lade ich wohl zu viel, ich könnte gucken, dass ich ein paar Modelle erst lade, wenn ich sie wirklich brauche. Das sollte aber trotzdem irgendwie im Hintergrund geschehen, ich will ja während dem Spiel nicht 30 kurze Aussetzer haben, jedesmal wenn ich ein Gebäude das erste mal baue. Die meisten Texturen werden ja schon in einem parallelen Thread geladen, dessen Laufzeit kann man wohl eigentlich abziehen. Bleiben ein paar Dinge, die ich halt tun muss (Heightmap laden, bevor ich Terrain rendern kann), und der Block mit den Sounds. Und das Warten auf den Mutex für die Aktualisierung des Ladefortschritts.

Interessant ist, dass 3D Modelle überhaupt nicht auftauchen. Ist die Festplattenlatenz unsichtbar für den Profiler? Andererseits sind die meisten Modelle auch einfach sehr low-poly, ich hab nur 24 MB Meshes (haha) aber vermutlich so ca. 1 GB an Texturen (die ja auch erstmal alle entpackt werden müssen).
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Jonathan
Establishment
Beiträge: 2602
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Profiling

Beitrag von Jonathan »

Oh, es gab tatsächlich ein dickes Problem mit dem Lade-Update-Thread. Hab den testweise deaktiviert und die Ladezeiten ca. gedrittelt (!). Muss mal schauen, ob man den nicht irgendwie effizient implementieren kann, jetzt hängt das Fenster halt komplett, davor gab es eine Ladeanimation und man konnte z.B. die Größe ändern etc.

Aber das ist ja soweit erstmal ein sehr schönes Ergebnis. An dieser Stelle hätte ich als letztes gesucht, das hatte ich überhaupt nicht im Blick. Da hat der Profiler mir echt gut weitergeholfen, hehe.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Schrompf
Moderator
Beiträge: 5125
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Profiling

Beitrag von Schrompf »

Sachma, durfte man nicht alles OpenGL nur aus dem aktuellen Thread heraus machen? Und für andere Threads gab's erst irgendein glMakeCurrent(), was angeblich sacklangsam ist, bevor man aus diesem Thread GL-Calls machen durfte. Vielleicht ist ja das der Grund, was bei Dir so viel Rechenzeit frisst? Dass Deine beiden Threads die ganze Zeit ein Tauziehen mit glMakeCurrent() machen?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2602
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Profiling

Beitrag von Jonathan »

So ein wenig.

Ursprünglich hatte ich einfach mein Spiel, das lädt halt und die Funktion nüdelt so 20 Sekunden vor sich her, bevor sie zurückkehrt. Was bedeutet, kein Event-Handler, kein Rendering, und ein Fenster ohne Inhalt, das auf nichts reagiert.

Mein etwas fauler, aber "genial simpler" Ansatz war jetzt: Das Spielobjekt wird in einem separaten Thread initialisiert, der danach beendet wird und das Spielobjekt wird dann ganz normal wie früher im Hauptthread verwendet. Während dem Laden kann der Hauptthread jetzt Nachrichten bearbeiten und Animationen anzeigen. Mit einem Schönheitsfehler: Das Spiel muss beim Laden OpenGL-Ressourcen anlegen, und dafür muss es den Kontext haben.

Also gibt es einen Mutex, in jedem Frame gibt der Hauptthread einmal den Kontext ab, jedesmal wenn der Ladethread ein Objekt anlegen will muss er entsprechend auf den Mutex warten. Weil das ein wenig kniffelig korrekt zu implementieren ist, hab ich die Logik ein wenig rumgedreht. Der Ladethread hat die meiste Zeit den Kontext, und gibt den in regelmäßigen Abständen gerade lange genug ab, um dem Hauptthread zu ermöglichen einen Frame zu rendern. Weil sich das dann anbietet wird dabei immer noch mitgeteilt, was denn gerade geladen wird. Was jedes mal passiert wenn ich eine Textur oder ein Modell oder einen Sound lade.

Das Problem war jetzt, dass ich wohl zu viele dieser Nachrichten erzeugt habe. Erstelle ich tausend Objekte (was schnell geht) müssen auch tausend Frames des Lade-Threads gerendert werden. Was mit VSYNC ein wenig dauert kann.

Die Lösung ist es jetzt erstmal, zum einen generell etwas weniger Nachrichten zu erzeugen, und zum anderen den Hauptthread mit der Ladeanimation nur noch maximal 20 mal pro Sekunde zu aktualisieren. Die Ladeanimation ist eine drehende CD, ist schon ok wenn die ein wenig ruckelt. Das Fenster reagiert auch nicht so schnell auf Events wie andere das tun, aber nicht so, dass es wirklich stört.

Das ganze Ladesystem ist noch etwas verfranzt, jetzt beim Aufschreiben merke ich etwa, dass ich vlt. gar nicht zwei verschiedene Threads bräuchte...
Aber gut, mein Ziel die Ladezeiten zu reduzieren, hab ich erstmal erreicht, jetzt kommt erstmal eine Runde Gameplay.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
NytroX
Establishment
Beiträge: 398
Registriert: 03.10.2003, 12:47

Re: Profiling

Beitrag von NytroX »

20 Sekunden wäre als Zeitrahmen evtl ok, wenn du ca. 50GB von der Festplatte in den RAM und dann auf die GPU schaufelst. Aber ich glaube so viel Speicher hat deine GPU nicht ;-)
Also falls du das Problem irgendwann nochmal angehst, würde ich dir auf jeden Fall noch empfehlen mal die Zeit zu messen, wie lange das Laden wirklich braucht, einfach Single-Threaded und in 2 Schritten:
1) Festplatte -> RAM
2) RAM -> GPU

Wenn du das dann wirklich asynchron machen musst, weils länger als 2-3 Sekunden dauert, dann würde ich nur 1 Thread für OpenGL nehmen.
Da drin kannst du dann mit glMapBuffer() die Textur in den RAM mappen (vorher mit glBufferData() aber einen neuen Buffer erzeugen).
Dann kannst du dem 2. Thread sagen, er soll das befüllen, und wenn er fertig ist dem 1. Thread wieder bescheid geben (evtl den Pointer mit volatile deklarieren).
Der 1. Thread macht dann das glUnmapBuffer() und den Upload zur GPU.
(während dem Befüllen durch den 2. Thread kann der 1. Thread die alte Proxy-Textur noch benutzen)

Und wenn das dann immer noch zu lange dauert, kann man das später nochmal optimieren und mittels DMA asynchron von OpenGL hochladen lassen.
Spätestens dann hast du überhaupt keine Verzögerung/Ruckler mehr.
Benutzeravatar
Schrompf
Moderator
Beiträge: 5125
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Profiling

Beitrag von Schrompf »

20s sind schon stattlich, in der Zeit kann man ne Menge Daten bewegen. Klingt aber, als würde Deine Mutex-Frame-Logik unnötig an die Framerate gekoppelt sein, und da kann man ja einfach reingrätschen, genau wie Du sagst.

Wenn Du Dich mit dem Thema noch beschäftigen möchtest, dann macht Nytrox schon nen guten Vorschlag: single-threaded ohne Ladescreen nebenher profilen, und zwar im Idealfall den dritten Run oder so, weil ab dann alles im Filecache ist und Du nur noch die echte OpenGL-Rechenzeit im Profiler hast.

Wenn es wirklich die Platte ist, dann dauert der erste Run viel länger als die nachfolgenden. Dann guck mal nach CreateFile(), CreateFileMapping(), MapViewOfFile() in der WinAPI oder mmap im Linux - Dateien in den Adressraum einfach reinzumappen ist merklich schneller als jedes fopen().
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2602
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: Profiling

Beitrag von Jonathan »

Schrompf hat geschrieben: 15.02.2025, 10:30 Wenn es wirklich die Platte ist, dann dauert der erste Run viel länger als die nachfolgenden. Dann guck mal nach CreateFile(), CreateFileMapping(), MapViewOfFile() in der WinAPI oder mmap im Linux - Dateien in den Adressraum einfach reinzumappen ist merklich schneller als jedes fopen().
Hat das denn Nachteile? Wenn nein, wieso ist das nicht eh Standard?
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
Krishty
Establishment
Beiträge: 8339
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Profiling

Beitrag von Krishty »

Im Allgemeinen macht man das nur für Read-Only-Daten, weil sich die Größe einer gemappten Datei nicht einfach ändern lässt. Auch lässt sich eine gemappte Datei unter Windows nicht löschen (unter Linux schon), was das Ersetzen von Daten bei laufendem Programm knifflig macht.

Standard sind Streaming Interfaces für Dateien, weil die auch Sockets, stdin & Co. abdecken. Während Win32 das Streaming gemappter Daten noch halbwegs möglich macht, hat Linux dafür null Fundament.

Fun Fact (aber wirklich die allerletzte Mikrooptimierung): Wenn du deine Texturen in einem Standard Data Layout ab D3D12 ablegst, kannst du das Speicherabbild direkt an D3D weiterleiten, ohne ein einziges Byte zu kopieren. Wenn ich sehe, dass du Texturen als PNG speicherst, ist ja die Frage: Was ist schneller – die Dekompression eines PNGs oder die Übertragungsrate nicht komprimierter Daten von der Festplatte? Seit dem Zeitalter der SSDs kann man das klar mit “unkomprimierte Daten von der Festplatte” beantworten.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten