Ich habe seit über einer Woche ein Problem in meiner DirectX 11 C ++ - Anwendung untersucht, und deshalb wende ich mich an die guten Leute in StackOverflow, die mir helfen könnten, diesen Fehler nachzuverfolgen.
Meine Anwendung wird meistens mit 60-90 Frames pro Sekunde laufen, aber alle paar Sekunden bekomme ich einen Frame, der etwa eine Drittelsekunde dauert. Nach vielen Nachforschungen, dem Debuggen und der Verwendung verschiedener Code-Profiler habe ich mich auf Aufrufe der DirectX-API beschränkt. Von einem langsamen Frame zum nächsten ist es jedoch nicht immer derselbe API-Aufruf, der die Verlangsamung verursacht. In meinem letzten Lauf sind die Aufrufe, die anhalten (immer für etwa eine Fünftelsekunde)
Nicht nur ist es nicht die gleiche Funktion, die zum Stillstand kommt, sondern jede dieser Funktionen (hauptsächlich die ersten zwei) kann der langsame Aufruf von verschiedenen Stellen in meinem Code von einem zum anderen sein.
Nach mehreren Profiling-Tools und meinen eigenen hochauflösenden Timern, die ich in meinen Code eingesetzt habe, um die Dinge zu messen, habe ich festgestellt, dass dieser "Schluckauf" in gleichmäßigen Abständen von knapp 3 Sekunden (~ 2,95) auftreten würde.
Diese Anwendung sammelt Daten von externer Hardware und verwendet DirectX, um diese Daten in Echtzeit zu visualisieren. Während die Anwendung ausgeführt wird, kann die Hardware im Leerlauf oder mit verschiedenen Geschwindigkeiten ausgeführt werden. Je schneller die Hardware geht, desto mehr Daten werden gesammelt und müssen visualisiert werden. Ich weise darauf hin, weil es nützlich sein kann, wenn man einige der Eigenschaften dieses Fehlers betrachtet:
Dieser Fehler tritt konsistent auf zwei verschiedenen Computern mit sehr ähnlicher Hardware auf (zwei GTX580-Karten). In neueren Versionen der Anwendung ist dieses Problem jedoch nicht aufgetreten. Leider hat der Code seitdem viele Änderungen erfahren, so dass es schwierig sein würde festzustellen, welche spezifische Änderung das Problem verursacht.
Ich habe den Grafiktreiber berücksichtigt und so auf die neueste Version aktualisiert, aber das hat keinen Unterschied gemacht. Ich erwog auch die Möglichkeit, dass eine andere Änderung an beiden Computern vorgenommen wurde, oder dass möglicherweise eine Aktualisierung der Software, die auf beiden Computern ausgeführt wird, Probleme mit der GPU verursachen könnte. Aber ich kann mir nichts anderes als Microsoft Security Essentials vorstellen, das auf beiden Computern ausgeführt wird, während die Anwendung ausgeführt wird, und ich habe bereits versucht, die Echtzeitschutzfunktion zu deaktivieren, ohne Erfolg.
Obwohl ich gerne die Ursache dafür hätte, ein externes Programm zu sein, das ich einfach ausschalten kann, mache ich mir schließlich Sorgen, dass ich etwas falsch / falsch mit der DirectX-API machen muss, die die GPU veranlasst, alle paar Anpassungen vorzunehmen Sekunden. Vielleicht mache ich etwas falsch in der Art, wie ich Daten auf der GPU aktualisiere (da die Verzögerung nur auftritt, wenn ich Daten zur Anzeige sammle). Dann hält der GPU alle paar Sekunden an und welche API-Funktion, die während eines Stalls aufgerufen wird, kann nicht so schnell zurückkehren, wie es normalerweise wäre?
Irgendwelche Vorschläge würden sehr geschätzt!
Danke, Tim
UPDATE (2013.01.21):
Ich gab schließlich nach und ging zurück durch vorherige Überarbeitungen meiner Anwendung, bis ich einen Punkt fand, an dem dieser Fehler nicht auftrat. Dann ging ich von Revision zu Revision, bis ich genau herausgefunden hatte, wann der Bug begann und die Quelle meines Problems ausfindig machte. Das Problem trat auf, nachdem ich ein "vorzeichenloses Integer" -Feld zu einem Vertex-Typ hinzugefügt hatte, dem ich einen großen Vertex-Puffer zuteile.Aufgrund der Größe des Vertexpuffers erhöhte diese Änderung die Größe 184,65 MB (1107,87 MB bis 1292,52). Da ich tatsächlich dieses zusätzliche Feld in meiner Vertex-Struktur benötige, habe ich andere Möglichkeiten gefunden, um die Gesamtgröße des Vertex-Puffers zu reduzieren, und habe es auf 704,26 MB heruntergesetzt.
Meine beste Vermutung ist, dass das Hinzufügen dieses Feldes und der zusätzliche Speicher, den es benötigt, dazu geführt haben, dass ich einen Grenzwert / Grenzwert für die GPU überschritten habe. Ich bin mir nicht sicher, ob es eine Überschreitung der Gesamtspeicherzuweisung oder eine Überschreitung einer Grenze für einen einzelnen Vertexpuffer war. Wie auch immer, es scheint, dass diese Überschreitung dazu führte, dass die GPU alle paar Sekunden einige zusätzliche Arbeit verrichten musste (vielleicht mit der CPU kommunizieren), und deshalb mussten meine Aufrufe an die API darauf warten. Wenn jemand irgendwelche Informationen hat, die die Implikationen großer Eckenpuffer verdeutlichen würden, würde ich es gerne hören!
Danke an alle, die mir ihre Zeit und Vorschläge gegeben haben.
1) Versuchen Sie, VSYNC zu drehen
2) Sie reservieren große Speicherbereiche? Versuchen Sie, Speicher zu Beginn des Programms zu reservieren und nicht zu löschen, überschreiben Sie es einfach (was Sie wahrscheinlich mit updatesupresource tun)
3) Fügen Sie die Interaktion mit dem Hardwaregerät in einen separaten Thread ein. Nachdem das Gerät die Daten vollständig an Ihre Anwendung übergeben hat, laden Sie es in die GPU. Lassen Sie das Gerät nicht die Kontrolle über den Haupt-Thread übernehmen. Ich vermute, dass das Gerät den Haupt-Thread immer wieder blockiert, und ich spekuliere völlig , aber wenn du Daten direkt vom Gerät auf die GPU kopierst, blockiert das Gerät gelegentlich und das verursacht die Verlangsamung.
Tags und Links c++ lag directx directx-11 frame-rate