Eine Sache, die mich verwirrte, wenn ich dieses Makro zum ersten Mal lese, ist: "Warum ist es eine Schleife, ist das nicht innerhalb des Kernels, der bereits parallelisiert wurde?" Die Antwort ist, die Schleife behandelt den Fall, wenn Sie mehr "Threads" haben, als Ihre GPU tatsächlich unterstützt. Wenn Sie beispielsweise eine parallelisierte Vektoraddition durchführen, haben Sie entschieden, dass Sie für Ihre GPU 512 Threads pro Block verwenden und maximal 4096 Blöcke planen (dies sind die Standardparameter in Caffe2). Dies bedeutet, dass Sie nur maximal 2097152 Threads einplanen können. Angenommen, Ihr Vektor hat tatsächlich 4M Elemente; Jetzt können Sie keinen Thread pro Element zuweisen. Also muss jeder Thread dafür verantwortlich sein, mehr als ein Element im Vektor zu summieren: dafür ist diese Schleife gedacht!
Hier ist ein kleineres Beispiel, das genau beschreibt, wie die Arbeit geplant wird. Angenommen, dass blockDim.x == 2
, gridDim.x == 2
und nthreads == 7
. Wenn wir dann einen GPU-Thread als (blockIdx.x, threadIdx.x)
identifizieren, weisen wir sie zu, um die folgenden Arbeiten an dem Vektor auszuführen: [(0,0), (0,1), (1,0), (1,1), (0,0), (0,1), (1,0)]
. Insbesondere können wir sehen, dass gemäß der Rastergröße nur vier GPU-Threads verfügbar sind; so für blockIdx.x == 0
threadIdx.x == 0
, index
wird Verarbeitung der Vektorelemente bei BEIDE 0
und 4
.