Was ist ein Bankenkonflikt? (Cuda / OpenCL-Programmierung durchführen)

95

Ich habe den Programmierleitfaden für CUDA und OpenCL gelesen und kann nicht herausfinden, was ein Bankkonflikt ist. Sie beschäftigen sich nur damit, wie man das Problem löst, ohne auf das Thema selbst einzugehen. Kann mir jemand helfen, es zu verstehen? Ich habe keine Präferenz, wenn die Hilfe im Kontext von CUDA / OpenCL oder nur Bankkonflikten im Allgemeinen in der Informatik steht.

geschmuggelte Pfannkuchen
quelle

Antworten:

105

Für nvidia (und auch für amd) gpus ist der lokale Speicher in Speicherbänke unterteilt. Jede Bank kann jeweils nur einen Datensatz adressieren. Wenn also ein Halfwarp versucht, Daten von / zu derselben Bank zu laden / zu speichern, muss der Zugriff serialisiert werden (dies ist ein Bankkonflikt). Für gt200 gpus gibt es 16 Bänke (32 Bänke für Fermi), 16 oder 32 Bänke für AMD gpus (57xx oder höher: 32, alles unter: 16)), die mit einer Körnigkeit von 32 Bit verschachtelt sind (also Byte 0-3 sind in Bank 1, 4-7 in Bank 2, ..., 64-69 in Bank 1 usw.). Für eine bessere Visualisierung sieht es im Grunde so aus:

Bank    |      1      |      2      |      3      |...
Address |  0  1  2  3 |  4  5  6  7 |  8  9 10 11 |...
Address | 64 65 66 67 | 68 69 70 71 | 72 73 74 75 |...
...

Wenn also jeder Thread in einem Halfwarp auf aufeinanderfolgende 32-Bit-Werte zugreift, gibt es keine Bankkonflikte. Eine Ausnahme von dieser Regel (jeder Thread muss auf seine eigene Bank zugreifen) sind Broadcasts: Wenn alle Threads auf dieselbe Adresse zugreifen, wird der Wert nur einmal gelesen und an alle Threads gesendet (für GT200 müssen alle Threads im Halfwarp auf die zugreifen Dieselbe Adresse, iirc fermi und AMD gpus können dies für eine beliebige Anzahl von Threads tun, die auf denselben Wert zugreifen.

Grizzly
quelle
3
Süßer Dank für das Bild und die Erklärung. Ich wusste nichts über Sendungen und das scheint eine wichtige Information zu sein :) Wie würde ich überprüfen, ob meine Ladevorgänge und Speicher keine Bankkonflikte im gemeinsam genutzten Speicher verursachen? Muss ich irgendwie an den Assembler-Code kommen oder gibt es andere Möglichkeiten?
geschmuggelte
3
Da das Auftreten von Bankkonflikten etwas ist, das zur Laufzeit bestimmt wird (was bedeutet, dass der Compiler nichts davon weiß, nachdem alle meisten Adressen zur Laufzeit generiert wurden), würde es nicht viel helfen, die kompilierte Version zu erhalten. Normalerweise mache ich das auf die altmodische Art und Weise. Ich nehme einen Stift und Papier und beginne darüber nachzudenken, was mein Code wo speichert. Immerhin sind die Regeln für das Auftreten von Bankkonflikten nicht so komplex. Andernfalls können Sie den nvidia OpenCL-Profiler verwenden (sollte mit sdk, iirc gebündelt sein). Ich denke, es hat einen Zähler für Warp-Serialisierungen.
Grizzly
1
Vielen Dank für den Hinweis auf Warp-Serialisierungen. Einer der Readme - Textdateien , die mit dem Rechen Profiler kommen , sagte diese,
smuggledPancakes
1
Ack, entschuldigen Sie den obigen Kommentar, aus irgendeinem Grund kann ich ihn nicht erneut bearbeiten. Wie auch immer, ich fand dies in der Readme-Datei des Compute-Profilers: "warp_serialize: Anzahl der Thread-Warps, die bei Adresskonflikten entweder in den gemeinsam genutzten oder in den konstanten Speicher serialisiert werden." Das ist großartig, dass ich leicht sehen kann, ob es Konflikte gibt, wenn ich nur die Profiler-Ausgabe betrachte. Wie können Sie herausfinden, ob es Bankkonflikte auf Stift und Papier gibt? Haben Sie aus Beispielen oder Tutorials gelernt?
geschmuggelt
1
Wie gesagt, die Zuordnung von Adressen zu Banken ist relativ einfach, daher ist es nicht so schwer herauszufinden, welche Zugriffe auf welche Bank gehen und ob es daher zu Bankkonflikten kommt. Das Papier ist nur für mehr Konfliktzugriffsmuster gedacht, auf die ich nicht verzichten kann.
Grizzly
13

Der gemeinsam genutzte Speicher, auf den parallel zugegriffen werden kann, ist in Module (auch Banken genannt) unterteilt. Wenn zwei Speicherorte (Adressen) in derselben Bank auftreten, tritt ein Bankkonflikt auf, bei dem der Zugriff seriell erfolgt, wodurch die Vorteile des parallelen Zugriffs verloren gehen.

Belwood
quelle
Hängt dies also damit zusammen, wann ein Half-Warp Speicher speichern oder laden möchte? 16 Threads versuchen, eine Speichertransaktion durchzuführen, und der Zugriff auf dieselbe Bank mit mehr als einem Thread führt zu einer serialisierten Verarbeitung. Wie stellt man außerdem sicher, dass Sie keine Daten in derselben Bank speichern / laden?
geschmuggelte
10

Mit einfachen Worten, ein Bankkonflikt ist ein Fall, in dem ein Speicherzugriffsmuster keine E / A auf die im Speichersystem verfügbaren Banken verteilt. Die folgenden Beispiele erläutern das Konzept:

Nehmen wir an, wir haben ein zweidimensionales 512x512-Array von Ganzzahlen und unser DRAM- oder Speichersystem enthält 512 Bänke. Standardmäßig werden die Array-Daten so angeordnet, dass arr [0] [0] zu Bank 0, arr [0] [1] zu Bank 1, arr [0] [2] zu Bank 2 geht .... arr [0] [511] geht zur Bank 511. Um zu verallgemeinern, besetzt arr [x] [y] die Banknummer y. Jetzt beginnt ein Code (wie unten gezeigt) mit dem Zugriff auf Daten in der Hauptform der Spalte, d. H. Wenn Sie x ändern, während Sie y konstant halten, führt dies dazu, dass alle aufeinander folgenden Speicherzugriffe dieselbe Bank treffen - daher ein Bankkonflikt.

int arr[512][512];
  for ( j = 0; j < 512; j++ ) // outer loop
    for ( i = 0; i < 512; i++ ) // inner loop
       arr[i][j] = 2 * arr[i][j]; // column major processing

Solche Probleme werden normalerweise von Compilern vermieden, indem das Array gepuffert wird oder eine Primzahl von Elementen im Array verwendet wird.

Nitin Kunal
quelle
7

(CUDA Bank Conflict) Ich hoffe, das wird helfen. Dies ist eine sehr gute Erklärung.

http://www.youtube.com/watch?v=CZgM3DEBplE

Prashant M.
quelle
1
Beachten Sie, dass von Antworten nur mit Links abgeraten wird. SO-Antworten sollten der Endpunkt einer Suche nach einer Lösung sein (im Vergleich zu einem weiteren Zwischenstopp von Referenzen, die im Laufe der Zeit veralten). Bitte fügen Sie hier eine eigenständige Zusammenfassung hinzu, wobei Sie den Link als Referenz behalten.
Kleopatra
Bitte erläutern Sie den Link, um das OP besser zu unterstützen.
Peter Foti
1
Dieses Video ist wirklich hilfreich! Und ich weiß nicht warum die Abstimmung! Es ist eine sehr gute Eingabe! +1
Gabriel