Ich frage mich, wie ich eine dynamische Schleifenfunktion am besten in einen Shader integrieren kann.
Erstens scheinen dynamische Arrays nicht möglich zu sein. Ist es also besser, ein Array mit maximaler Größe zu erstellen und nur einen Teil davon zu füllen oder Arrays mit vordefinierten Größen zu definieren?
Was ist dann der beste Weg, um über dieses Array zu iterieren?
Ist es besser, eine ungerollte Schleife oder eine dynamische Schleife für 4 bis 128 Iterationen zu verwenden? Ich habe auch gesehen, dass es möglich ist, es auf eine maximal vordefinierte Anzahl von Iterationen abzuwickeln und es dann mit einer Bedingung wie zu stoppen if (i == myCurrentMaximumIterationNumber)
.
Antworten:
Shader-Compiler sind äußerst aggressiv beim Abrollen, da frühe HW häufig keine Flusskontrolle hatten und die Kosten für neuere HW variieren können. Wenn Sie einen Benchmark haben, gegen den Sie aktiv testen, und eine Reihe relevanter Hardware, versuchen Sie Dinge, um zu sehen, was passiert. Ihre dynamische Schleife ist für Entwicklerinterventionen besser geeignet als eine statische Schleife. Es ist jedoch immer noch ein guter Rat, sie dem Compiler zu überlassen, es sei denn, Sie haben einen Benchmark zur Verfügung. Mit einem Benchmark lohnt sich die Erkundung (und macht Spaß).
Übrigens ist der größte Verlust bei einer dynamischen Schleife auf einer GPU, dass einzelne "Threads" in einer Wellenfront / einem Warp zu unterschiedlichen Zeiten beendet werden. Die Threads, die später gestoppt werden, zwingen alle, die vorzeitig beendet werden, NOPs auszuführen.
Verschachtelte Schleifen sollten sorgfältig durchdacht werden: Ich habe einen blockbasierten Entropiedecoder implementiert, der Läufe von Nullen codiert (für JPEG-ähnliche Komprimierung). Die natürliche Implementierung bestand darin, die Läufe in einer engen inneren Schleife zu dekodieren - was bedeutete, dass oft nur ein Thread Fortschritte machte; Durch Abflachen der Schleife und explizites Testen in jedem Thread, ob gerade ein Lauf dekodiert wurde oder nicht, habe ich alle Threads durch die Schleife mit fester Länge aktiv gehalten (die dekodierten Blöcke hatten alle die gleiche Größe). Wenn die Threads wie CPU-Threads wären, wäre die Änderung schrecklich gewesen, aber auf der GPU, auf der ich lief, konnte ich die Leistung um das Sechsfache steigern (was immer noch schrecklich war - es gab nicht genügend Blöcke, um die GPU zu beschäftigen - aber es war ein Proof of Concept).
quelle