Effizientes Lösen linearer Gleichungssysteme über GF(2) - CDC ...
Effizientes Lösen linearer Gleichungssysteme über GF(2) - CDC ...
Effizientes Lösen linearer Gleichungssysteme über GF(2) - CDC ...
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
2.6. OPTIMIERTES PROGRAMMIEREN MIT CUDA 33<br />
ist auch bei der Wahl der Blockgröße wichtig. Je nach Menge des benötigten<br />
gemeinsamen Speichers und der Register kann die Dimension entsprechend<br />
angepasst werden.<br />
Größere Blöcke führen nicht automatisch zu einer höheren Auslastung. Ein<br />
Block mit 512 Threads auf einem Device mit einer Compute Capability von<br />
1.1 führt zu einer Auslastung von 66%, da bei einem Maximum von 768<br />
Threads pro Multiprozessor nur ein Block aktiv sein kann. Besteht dagegen<br />
ein Block aus 256 Threads, so beträgt die Auslastung 100%, da drei Blöcke<br />
geladen werden können (Vergleiche B.2).<br />
Die Anzahl der Threads pro Block sollte durch die Warpgröße teilbar sein<br />
um ungenutzte Berechnungsressourcen durch Unterbelegung zu vermeiden.<br />
Wenn mehrere Blöcke pro Prozessor verarbeitet werden ist es außerdem empfehlenswert,<br />
dass jeder <strong>über</strong> mindestens 64 Threads verfügt. Besser ist jedoch<br />
ein Wert zwischen 128 und 256. Die Blockbreite und Blockhöhe sollte bei<br />
Devices mit einer Compute Capability von 2.0 durch die Warpgröße und bei<br />
Grafikkarten mit einer Compute Capability von 1.x durch die halbe Warpgröße<br />
teilbar sein. Dies liegt darin begründet, dass im besten Fall der erste<br />
Thread eines aktiven Warps auf das erste Element in dem Segment des globalen<br />
Speichers zugreift (Siehe auch 2.5.4).<br />
2.6.2 Optimierung von Speicherzugriffen<br />
Das Verbessern von Zugriffen auf die jeweiligen Speicher ist eines der wichtigsten<br />
Gebiete der Optimierung. Der erste Schritt ist Datenverkehr mit einer<br />
geringen Bandbreite zu meiden. Dazu gehört zum Beispiel der Transfer zwischen<br />
CPU und GPU, welcher <strong>über</strong> einen PCI Express (PCIe) Bus läuft. Des<br />
Weiteren sollten Daten in möglichst großen Paketen <strong>über</strong>tragen werden.<br />
Die peak Bandbreite des Grafikkartenspeichers ist höher, als die zwischen<br />
Host und Device. Daher kann in einigen Fällen eine bessere Gesamtzeit erreicht<br />
werden, wenn ein Kernel auch Anweisungen bearbeitet, die nicht parallel<br />
durchgeführt werden können anstatt diese von der CPU berechnen zu<br />
lassen. Vor allem sollten Datenstrukturen auf der Grafikkarte verbleiben, die<br />
nur zum Speichern von Zwischenschritten benötigt werden.<br />
Anfragen an den globalen Speicher haben durch die auftretende Latenz eine<br />
geringe Bandbreite, wodurch es empfehlenswert ist öffter Daten in den<br />
gemeinsamen Speicher zu <strong>über</strong>tragen. Außerdem sollten so oft wir möglich<br />
Adressräume verwendet werden, die <strong>über</strong> einen Cache verfügen, wie der für<br />
Texturen und Konstanten.