Hier laden Sie sich eine zuvor bezahlte Vorbestellung herunter. Die Installation endet, Sie starten das Spiel. Alles läuft gut: Das Spiel fliegt mit einer Bildrate von 60 FPS. Zumindest sagt Ihnen das der Frame-Zähler in Ihrem GPU-Overlay. Aber etwas läuft schief. Sie bewegen Ihre Maus hin und her und bemerken, dass das Spiel ... friert.
Wie ist das möglich? Welche anderen frieren bei 60 FPS ein?
Es mag lächerlich erscheinen, bis Sie selbst darauf stoßen. Wenn Sie solche Friese getroffen haben, haben Sie es wahrscheinlich schon geschafft, sie zu hassen.
Dies sind keine Verzögerungen. Keine niedrige Bildrate. Das ist erschütternd. Mit hoher FPS und idealer ultraschneller Konfiguration.
Was ist es, woher kommt es und gibt es einen Weg, es loszuwerden? Lass es uns jetzt herausfinden.
Seit der Einführung der ersten Arcade-Automaten in den 70er Jahren laufen Videospiele mit 60 FPS. Es wird normalerweise davon ausgegangen, dass das Spiel mit der gleichen Geschwindigkeit wie das Display läuft. Erst nach der Popularisierung des 3D-Spielens mussten wir uns einer niedrigeren Bildrate stellen. In den 90er Jahren, als "3D-Karten" (jetzt "GPUs" genannt) das Software-Rendering zu ersetzen begannen, spielten die Leute mit 20 Bildern pro Sekunde, und 35 FPS wurden bereits als Frequenz für ernsthaften Netzwerkwettbewerb angesehen.
Jetzt haben wir superschnelle Autos, die natürlich mit 60 FPS fliegen können. Es sieht jedoch so aus, als ob mehr Leistung als je zuvor unzufrieden ist. Wie ist das möglich?
Es ist nicht so, dass Spiele nicht schnell genug sind. Und die Tatsache, dass sie auch bei hoher Leistung einfrieren.
Wenn Sie in den Spielforen stöbern, werden Sie wahrscheinlich so etwas in den Schlagzeilen sehen:
PC-Spieler beklagen sich häufig darüber, dass Spiele unter Statter leiden, selbst wenn es keine Probleme mit der Bildrate gibt.
Es kann davon ausgegangen werden, dass es sich um Einzelfälle handelt, aber solche Annahmen werden durch die Google- Suchstatistik widerlegt :
In den letzten 5 Jahren ist das Streuen (relativ) eher ein Problem als die Leistung geworden.
(Beachten Sie, dass dies relative Werte sind. Es ist nicht so, dass Menschen häufiger nach Informationen über Streuung als über Bildraten im Allgemeinen suchen. Während die Anzahl der Suchvorgänge nach Bildraten gleich bleibt, werden Suchanfragen nach Angaben immer häufiger. )
Jahrzehntelange Suche nach den Gründen für die Streuung
Der Patient lebt definitiv. Er ärgert sich nur oft.
Der Autor stieß dieses Problem zum ersten Mal im Jahr 2003 an, als er an Serious Sam 2 arbeitete. Die Leute begannen, Fälle zu melden, in denen Bildschirm- und Mausbewegungen während des Testens auf einer leeren Ebene nicht reibungslos waren. Dies wurde von einem sehr spezifischen Muster im Frameraten-Diagramm begleitet, das das Entwicklungsteam "Herzschlag" nannte.
Der erste Gedanke war, dass sich irgendwo im Code ein Fehler eingeschlichen hatte, aber niemand konnte ihn finden. Es schien, dass das Problem zufällig auftrat und verschwand - beim Neustart des Spiels, beim Neustart des Computers ... aber es hat sich gelohnt, Leistungsparameter zu ändern, und es verschwand. Dann konnten Sie den Parameter wieder ändern und alles funktionierte weiterhin perfekt. Geisterproblem.
Offensichtlich war Sam nicht das einzige Problem. Beim Starten anderer Spiele sah es genauso aus, was darauf hindeutete, dass mit den Treibern etwas nicht stimmte. Die Streuung hing jedoch nicht vom Hersteller Ihrer GPU ab. Es fand sogar mit verschiedenen APIs statt (OpenGL, DirectX 9, DirectX 11 ...). Das einzige, was gemeinsam blieb, war, dass hier und da auf einigen Maschinen und Spielszenen Statter auftraten.
Mit der Veröffentlichung neuer Spiele trat dieses Problem weiterhin auf und verschwand. Bisher waren nur einige Benutzer davon betroffen, und alles beschränkte sich auf Anfragen des technischen Supports, einige Leistungsparameter zu ändern - was manchmal hilfreich war und manchmal nicht, wie Sie nie erfahren haben.
Dann, plötzlich, an einem schönen Wintertag Anfang 2013, entdeckten die Jungs von Croteam ein weiteres Beispiel für dieses Problem, das zu dieser Zeit relativ konsistent reproduziert werden konnte - diesmal auf einer der Ebenen in Serious Sam 3. Sie spielten lange mit dieser Szene, bis sie plötzlich aufging. Es war so einfach - kein Wunder, dass es für ein Jahrzehnt der Öffentlichkeit entging.
Durch Ändern nur einer einfachen Option in der Spiel-Engine konnten sie dieses Problem lösen. Es wurde jedoch sofort klar, dass die Lösung tatsächlich viel mehr Zeit und Mühe erfordern würde. Und das nicht nur von einem bestimmten Team, sondern vom gesamten Gaming-Ökosystem: GPU-Treiberentwickler, API-Wartungsspezialisten, Betriebssystemanbieter - alle.
Was ist die ganze Zeit passiert?
So sieht es aus, wenn das Spiel selbst bei 60 FPS langsamer wird. Sie hätten in jedem modernen Spiel etwas Ähnliches erleben können, und wahrscheinlich denken Sie zuerst, dass das Spiel nicht optimiert ist. Lassen Sie uns diese Theorie noch einmal überdenken.
Wenn das Spiel "zu langsam" ist, bedeutet dies, dass es an einigen Stellen nicht in der Lage ist, ein Bild schnell genug zu rendern, und der Monitor muss das vorherige Bild erneut anzeigen. Wenn wir Videos mit 60 Bildern pro Sekunde aufnehmen, sollten daher "verworfene Bilder" angezeigt werden - wenn das nächste Bild nicht rechtzeitig angezeigt wurde, weshalb dasselbe zweimal angezeigt wurde.
Dies geschieht jedoch nur, wenn Sie die gesamte Animation abspielen. Wenn Sie es Frame für Frame durchgehen würden, würden Sie keine Lücken finden.
Wie ist das möglich?
Schauen wir uns das genauer an. Im Folgenden finden Sie einen direkten Vergleich zwischen idealem flüssigem Video und inszeniertem Video:
Sechs aufeinanderfolgende Bilder mit genauem Timing. Über - korrekt positionierte Frames, unter - Frames mit Streuung.
Sie können hier zwei Dinge sehen: Erstens arbeiten sie wirklich mit der gleichen Geschwindigkeit: Immer wenn ein neues Bild oben angezeigt wird (richtig), wird unten ein neues Bild angezeigt (streifend). Zweitens scheinen sie sich aus irgendeinem Grund etwas anders zu bewegen - es gibt eine merkliche "Lücke" in der Mitte des Bildes, die zwischen einer größeren und einer kleineren Zeitteilung schwankt.
Die aufmerksamsten mögen ein weiteres merkwürdiges Detail bemerken: Das untere Bild ist angeblich "langsamer" ... tatsächlich ist es dem richtigen "voraus". Seltsam, nicht wahr?
Wenn wir uns mehrere aufeinanderfolgende Frames und deren Timing ansehen, sehen wir noch etwas Interessantes: Die ersten beiden Frames sind perfekt synchronisiert, aber im dritten Frame ist der Baum im "langsameren" Video seinem Gegenstück im "richtigen" deutlich voraus. Video (rot eingekreist) ... Sie können auch feststellen, dass dieser Rahmen deutlich länger gedauert hat (gelb eingekreist).
Warten Sie, warten Sie ... aber wenn das Video "langsamer" ist und der Frame "länger" gedauert hat, wie kann es weitergehen?
Um weitere Erklärungen zu verstehen, müssen Sie zunächst verstehen, wie moderne Spiele und andere 3D-Anwendungen im Allgemeinen Animation und Rendering ausführen.
Eine kurze Geschichte der Frame-Synchronisation
Vor langer Zeit, in einer weit entfernten Galaxie ... als Entwickler die ersten Videospiele erstellten, taten sie dies normalerweise basierend auf der genauen Bildrate, mit der das Display lief. In NTSC-Regionen, in denen Fernsehgeräte mit 60 Hz arbeiten, bedeutet dies 60 Bilder pro Sekunde, und in PAL / SECAM-Regionen, in denen Fernsehgeräte mit 50 Hz arbeiten, 50 Bilder pro Sekunde.
Die meisten Spiele waren sehr einfache Konzepte, die auf fester Hardware ausgeführt wurden - normalerweise eine Arcade-Konsole oder ein bekannter "Heim-Mikrocomputer" wie ZX Spectrum, C64, Atari ST, Amstrad CPC 464, Amiga usw. So erstellen und testen Bei Spielen für einen bestimmten Computer und eine bestimmte Framerate konnte der Entwickler immer zu 100% sicher sein, dass die Framerate nirgendwo sinken würde.
Objektgeschwindigkeiten wurden auch in "Personal" -Einheiten gespeichert. Sie mussten also nicht wissen, wie viele Pixel pro Sekunde sich das Zeichen bewegen würde, sondern wie viele Pixel im Rahmen. In Sonic The Hedgehog für Sega Genesis beträgt diese Geschwindigkeit beispielsweise 16 Pixel pro Frame. Viele Spiele hatten sogar separate Versionen für PAL- und NTSC-Regionen, in denen Animationen speziell für 50 bzw. 60 FPS von Hand gezeichnet wurden. Tatsächlich war es einfach unmöglich, mit einer anderen Bildrate zu arbeiten.
Und da Spiele im Laufe der Zeit auf verschiedenen Geräten ausgeführt wurden, einschließlich PCs mit ständig wachsender und aktualisierter Hardware, war es unmöglich, genau zu wissen, mit welcher Framerate das Spiel laufen würde. Diese Tatsache wurde durch die Tatsache verstärkt, dass die Spiele selbst komplexer und unvorhersehbarer geworden sind - dies macht sich insbesondere bei 3D-Spielen bemerkbar, bei denen es große Unterschiede in der Komplexität der Szene geben kann, die manchmal sogar von den Spielern selbst bestimmt werden. Zum Beispiel liebt es jeder, auf Stapel von Treibstofffässern zu schießen, was eine bunte Reihe von Explosionen verursacht ... und einen unvermeidlichen Rückgang der Bildrate. Aber da es Spaß macht, stört es niemanden wirklich.
Daher ist es schwierig vorherzusagen, wie lange es dauern wird, einen Frame zu modellieren und zu rendern. (Bitte beachten Sie, dass wir auf modernen Konsolen davon ausgehen können, dass die Hardware repariert ist, die Spiele selbst jedoch noch nicht vorhersehbar und komplex sind.)
Wenn Sie nicht sicher sind, mit welcher Framerate das Spiel funktioniert, müssen Sie die aktuellen Frequenzframes messen und passen Sie ständig die Physik des Spiels und die Geschwindigkeit der Animation dafür an. Wenn ein Bild eine 1/60 Sekunde (16,67 ms) benötigt und Ihr Charakter mit 10 m / s läuft, bewegt er sich in jedem Bild um 1/6 Meter. Wenn der Frame jedoch plötzlich 1/30 Sekunde (33,33 ms) dauert, müssen Sie den Charakter bereits um 1/3 Meter pro Frame (zweimal "schneller") bewegen, damit er sich mit der gleichen scheinbaren Bewegung weiterbewegt Geschwindigkeit.
Wie arrangiere ich das? In der Regel misst das Spiel die Zeit am Anfang benachbarter Frames und berechnet die Differenz. Dies ist eine ziemlich einfache Methode, aber sie funktioniert sehr gut.
Vielmehr hat es vorher sehr gut funktioniert. In den 90er Jahren, als 35 FPS als Geschwindigkeit angesehen wurden, waren die Leute mehr als zufrieden damit. Zu dieser Zeit waren Grafikkarten jedoch kein so wichtiger Bestandteil des PCs, und der Zentralprozessor hatte die Kontrolle über alles, was auf dem Bildschirm geschah. Wenn Sie keinen 3D-Beschleuniger hatten, zeichnete er sogar Objekte von selbst. So wusste er genau, wann sie auf den Bildschirm kommen würden.
Die Situation heute
Im Laufe der Zeit tauchten immer ausgefeiltere GPUs auf, die unweigerlich immer "asynchroner" wurden. Dies bedeutet, dass die GPU diesen Befehl einfach in einem Puffer speichert, wenn die CPU die GPU auffordert, etwas auf den Bildschirm zu zeichnen, damit die CPU während des Renderns der GPU weitermachen kann. Letztendlich führt dies zu einer Situation, in der die CPU der GPU mitteilt, wann das Ende des Frames kommt, und die GPU, während sie dies unter ihren Daten speichert, es nicht wirklich als eine Priorität betrachtet - schließlich ist es immer noch so einige der zuvor ausgegebenen Befehle verarbeiten ... Der Frame wird nur dann auf dem Bildschirm angezeigt, wenn er alles getan hat, was zuvor geladen wurde.
Wenn das Spiel versucht, die Zeit durch Subtrahieren der Zeitstempel zu Beginn von zwei aufeinanderfolgenden Frames zu berechnen, ist die Relevanz dieses Spiels, ehrlich gesagt, höchst fraglich. Kehren wir also zu unserem Beispiel zurück. Dort hatten wir folgende Frames:
Sechs aufeinanderfolgende Frames mit genauem Timing. Die obere Reihe ist korrekt, die untere Reihe hat einen störenden Effekt.
In den ersten beiden Bildern beträgt die Bildzeit 16,67 ms (oder 1/60 Sekunde), und die Kamera bewegt sich in Groß- und Kleinschreibung um den gleichen Betrag, sodass die Bäume synchron sind. Im dritten Frame (unten mit Streuung) stellte das Spiel fest, dass die Frame-Zeit 24,8 ms beträgt (dh mehr als 1/60 Sekunde), und glaubt daher, dass die Framerate gesunken ist, und beeilt sich, um mit dem aufzuholen fehlt ... nur um festzustellen, dass im nächsten Bild die Zeit nur 10,7 ms beträgt, wodurch die Kamera langsamer wird und die Bäume nun mehr oder weniger wieder synchronisiert sind.
Was ist los? Die von einem Spiel gemessenen Frame-Zeiten schwanken aufgrund verschiedener Faktoren - insbesondere bei einem ausgelasteten Multitasking-System wie einem PC. Daher geht das Spiel zu bestimmten Zeitpunkten davon aus, dass die Frequenz von 60 FPS gesunken ist, und generiert Animationsframes, die für eine niedrigere Framerate ausgelegt sind. Aufgrund der Asynchronität der GPU kehrt sie jedoch immer wieder auf die gleichen 60 Bilder pro Sekunde zurück.
Dies ist erschütternd - eine Animation, die für eine variable Bildrate (Herzfrequenz) generiert wurde und mit der tatsächlich korrekten festen Bildrate angezeigt wird.
Im Wesentlichen können wir also davon ausgehen, dass es kein Problem gibt - alles läuft reibungslos, das Spiel weiß es einfach nicht.
Dies bringt uns zu dem, worüber wir am Anfang des Artikels gesprochen haben. Wenn wir endlich die Ursache des Problems herausgefunden haben (obwohl wir wissen, dass dies eine Illusion eines Problems ist - es gibt wirklich kein Problem, oder?), Können wir die folgende magische Pille anwenden.
Was ist diese Pille? In der Serious Engine wird es als sim_fSyncRate = 60 bezeichnet. In einfachen Worten bedeutet dies Folgendes : " Ignorieren Sie all diese Spielereien vollständig und tun Sie so, als würden wir immer stabile 60 Bilder pro Sekunde messen ." Und alles läuft reibungslos - nur weil von Anfang an alles reibungslos funktioniert hat! Der einzige Grund für die Angabe war, dass das Timing für die Animation falsch war.
Und was ist das alles?
Die Lösung ist also so einfach?
Leider gibt es keine. Es war nur auf Tests. Wenn wir aufgehört haben, die Bildrate unter realen Bedingungen zu messen, und einfach angenommen haben, dass sie immer 60 FPS entspricht, dann fällt sie früher oder später aus irgendeinem Grund, wenn sie unter 60 fällt - und auf einem PC: Programme, die im Hintergrund laufen, Energie Erhaltung oder Überhitzungsschutz, wer weiß - dann wird alles langsamer.
Wenn wir also die Frame-Zeit messen, tritt eine Streuung auf, und wenn nicht, kann sich irgendwann alles verlangsamen. Und dann was?
Die eigentliche Lösung wäre, nicht die Start- / Endzeit des Renderns eines Frames zu messen, sondern die Zeit, zu der das Bild auf dem Bildschirm angezeigt wird.
Aber wie kann das Spiel wissen, wann ein Frame tatsächlich auf dem Bildschirm angezeigt wird?
Auf keinen Fall: Im Moment ist das unmöglich.
Komisch aber wahr. Man würde erwarten, dass dies ein Kernmerkmal jeder Grafik-API ist. Aber nein: Abgesehen davon haben sie sich in allen anderen Aspekten verändert. Es ist nicht sicher, wann der Frame tatsächlich auf dem Bildschirm angezeigt wird. Sie können herausfinden, wann das Rendern beendet ist. Dies ist jedoch nicht dasselbe wie die Anzeigezeit.
Was jetzt?
Nun, es ist nicht so schlimm. Viele Leute arbeiten aktiv an der Implementierung der Unterstützung für die korrekte Frame-Synchronisation für verschiedene APIs. Die Vulkan-API verfügt bereits über eine Erweiterung namens VK_GOOGLE_display_timing, die nachweislich dieses Konzept implementiert hat, jedoch nur für eine begrenzte Anzahl von Geräten verfügbar ist.
Es wird daran gearbeitet, ähnliche und bessere Lösungen bereitzustellen. Ich würde gerne glauben, dass dies bereits in allen wichtigen Grafik-APIs der Fall ist. Wann? Es ist schwer zu sagen, da das Problem tief in verschiedene Betriebssystem-Subsysteme eingreift.
Wir hoffen jedoch, dass es bald einer breiteren Öffentlichkeit zugänglich sein wird.
Verschiedene Vorbehalte und andere Details
Wir gehen davon aus, dass dies das Ende des Haupttextes ist. Die folgenden Abschnitte sind "Bonusfunktionen", die weitgehend unabhängig voneinander und von den oben genannten sind.
"Komponist"
Ist das ein Milchglaseffekt? Ja, deshalb müssen wir einen Komponisten haben. Ziemlich wichtig, nicht wahr?
Hinter den Kulissen befindet sich ein Konzept namens Compositing Window Manager , auch als Composer bekannt. Dies ist ein System, das jetzt in jedem Betriebssystem vorhanden ist und es Fenstern ermöglicht, transparent zu sein, einen unscharfen Hintergrund, Schatten usw. zu haben. Komponisten können noch weiter gehen und Ihre Programmfenster in 3D anzeigen. Zu diesem Zweck übernimmt der Komponist die Kontrolle über den letzten Teil des Rahmens und entscheidet, was damit geschehen soll, kurz bevor er auf den Monitor trifft.
In einigen Betriebssystemen kann der Composer im Vollbildmodus deaktiviert werden. Dies ist jedoch nicht immer möglich, und können wir das Spiel auch in solchen Fällen nicht im Fenstermodus ausführen?
Power & Thermal Management VS Rendering-Komplexität
Wir müssen auch die Tatsache berücksichtigen, dass moderne CPUs und GPUs nicht mit einer festen Frequenz arbeiten, sondern beide Systeme haben, die ihre Geschwindigkeit abhängig von der Last und der aktuellen Temperatur nach oben und unten anpassen. Daher kann das Spiel nicht einfach davon ausgehen, dass sie von Bild zu Bild dieselbe Geschwindigkeit haben. Auf der anderen Seite können das Betriebssystem und die Treiber nicht erwarten, dass das Spiel in jedem Frame die gleiche Menge an Arbeit leistet. Komplexe Kommunikationssysteme zwischen zwei Parteien müssen so konzipiert sein, dass all dies berücksichtigt wird.
Könnten wir nicht einfach ...
Konnte nicht. :) Normalerweise wird die GPU-Zeitmessung als Alternative zur Anzeigezeit angeboten. Dies berücksichtigt jedoch nicht die Anwesenheit eines Komponisten und die Tatsache, dass keiner der GPU-Rendering-Timer tatsächlich direkt mit dem Display-Update synchronisiert wird. Für eine perfekte Animation müssen wir auf jeden Fall genau wissen, wann das Bild angezeigt wurde und nicht, wann es fertig gerendert wurde.