In allen Codebeispielen, die ich mir angesehen habe, sieht die Spieleschleife ungefähr so aus:
while(true)
{
InputAndUpdate();
Draw();
SwapBuffers();
}
Zerstört dies jedoch nicht die Parallelität zwischen CPU und GPU? Nach dem Aufruf der Swap-Puffer sitzt die GPU untätig da, während die CPU die Eingabe und Aktualisierung übernimmt. Wenn die CPU die Ausgabe der Zeichenbefehle beendet hat, wartet sie, bis das Rendern der GPU abgeschlossen ist. Warum wird es nicht so gemacht? ::
while(true)
{
Draw(); //First issue the draw commands
InputAndUpdate(); //Update while the GPU is busy rendering
SwapBuffers(); //Now block and wait for the GPU to finish
}
architecture
rendering
game-loop
Hannesh
quelle
quelle
Antworten:
Dies wäre der Fall, wenn Sie keinen zusätzlichen Rückpuffer zum Rendern haben (Doppelpufferung). Auf diese Weise kann die CPU weitermachen und Dinge erledigen, ohne auf den eigentlichen Pufferaustausch warten zu müssen (was normalerweise der Fall ist, da Sie den hinteren Puffer erst ändern können, wenn er ohne Risiko in den vorderen Puffer kopiert wurde korrumpieren, was Sie gerade gerendert haben). Wenn ein Draw-Aufruf oder ein Swap ausgeführt wird, wird die Anforderung in einen Puffer mit Befehlen gestellt, die die GPU verarbeiten kann, sodass die CPU andere Aufgaben ausführen kann, während die GPU im Rückstand ist. So erhält moderne Hardware Parallelität. Ich glaube, D3D hat eine Begrenzung für die Anzahl der Frames, die Sie vor dem Blockieren eines "Swaps" rendern können (Sie ').
Das Konzept einer Spielschleife wie in beiden obigen Beispielen ist ziemlich veraltet. Mit der Einführung mehrerer Verarbeitungseinheiten auf der CPU können Sie möglicherweise auf einem Thread rendern, während Sie einige Aktualisierungsarbeiten an einem oder mehreren anderen Threads ausführen. Möglicherweise möchten Sie sich mit dem Konzept der Jobwarteschlangen befassen, um die gesamte verfügbare CPU-Verarbeitungsleistung zu maximieren.
quelle
Die Lösung, die Sie gewählt haben, führt nicht dazu, dass CPU und GPU parrarel funktionieren. Sie ändert lediglich die Reihenfolge, in der sie aufeinander warten Um das volle Potenzial von CPU und GPU auszuschöpfen, müssen Sie Zeichnen und Aktualisieren in zwei verschiedenen Threads aufrufen und einen weiteren zweiten Puffer für die CPU-Aktivitäten verwenden (damit CPu Aktualisierungsergebnisse in Puffer 2 generiert) GPU aus Puffer 1 lesen und wenn die CPU mit Puffer 1 arbeitet GPU verwenden Sie Puffer 2 genau wie Swap-Puffer, die die GPU verwendet, um Änderungen im bereits gezeichneten Frame zu verhindern.
quelle