Abbruch Overhead vs Kontrolle Flag

8

Ich benutzte eine naive Prim-generierte Funktion. Dieser Code benötigt ungefähr 5,25 Sekunden, um 10k Primzahlen zu erzeugen (device_primes [0] enthält die bereits gefundenen Primzahlen, die verbleibende Position die gefundenen Primzahlen).

%Vor%

Ich habe gerade damit begonnen, den Code zu optimieren, und ich habe die folgende Änderung vorgenommen:

%Vor%

Ich habe jetzt:

%Vor%

Jetzt kann ich 10k in 0.707s erzeugen. Ich habe mich nur gefragt, warum solch eine Beschleunigung mit einer so einfachen Modifikation, ist es so schlimm?

    
dreamcrash 05.11.2012, 16:38
quelle

1 Antwort

2

Wie Tony vorgeschlagen hat, kann eine abweichende Codeausführung zu einer erheblichen Verlangsamung des GPU-Codes führen, was dazu führt, dass ein bestimmter Code seriell und nicht parallel ausgeführt wird. In der langsamen Version des obigen Codes divergieren Threads, die den Bruch treffen, vom fortlaufenden Code.

Der cuda-c-Programmierleitfaden ist eine gute Quelle für GPU-Programmiertechniken . Hier ist, was es über den Kontrollfluss sagt :

  

Jede Flusssteueranweisung (falls, wechseln, tun, für, während) kann den effektiven Anweisungsdurchsatz signifikant beeinflussen, indem sie bewirkt, dass Threads desselben Warps divergieren (d. h. unterschiedlichen Ausführungspfaden folgen). Wenn dies geschieht, müssen die verschiedenen Ausführungspfade serialisiert werden, wodurch die Gesamtzahl der für diesen Warp ausgeführten Befehle erhöht wird. Wenn alle verschiedenen Ausführungspfade abgeschlossen sind, konvergieren die Threads zurück zum selben Ausführungspfad.

Neuere nvidia Hardware- und Cuda-Versionen können einige Verzweigungen ein wenig besser behandeln als ältere Versionen, aber es ist immer noch am besten, wenn möglich Verzweigungen zu vermeiden.

    
Eric Olson 25.11.2012, 23:07
quelle

Tags und Links