🐞Schritt-Debugger für CUDA-Kernels

Alle Threads werden im Browser nachgebildet – jeder Speicherzugriff wird gezählt und das Ergebnis mit einer CPU-Referenz verglichen. Vor und zurück mit den Knöpfen oder den Pfeiltasten ← →. Es läuft keine echte GPU: Reihenfolgen innerhalb eines Schritts sind vereinfacht.

🧪 echt im Browser simuliert – alle Threads, jeder Zugriff gezählt
Schritt 1 / 13 · Tasten ← →
1__global__ void vecAdd(const float* a, const float* b, float* c, int n) {
2 int i = blockIdx.x * blockDim.x + threadIdx.x; // globaler Index
3 if (i < n) // Wächter: überzählige Threads tun nichts
4 c[i] = a[i] + b[i];
5}
6
7int main() {
8 const int n = 10;
9 float h_a[n], h_b[n], h_c[n]; // Host-Arrays (im Arbeitsspeicher)
10 float *d_a, *d_b, *d_c; // Zeiger in den GPU-Speicher
11 cudaMalloc(&d_a, n * sizeof(float));
12 cudaMalloc(&d_b, n * sizeof(float));
13 cudaMalloc(&d_c, n * sizeof(float));
14 cudaMemcpy(d_a, h_a, n * sizeof(float), cudaMemcpyHostToDevice);
15 cudaMemcpy(d_b, h_b, n * sizeof(float), cudaMemcpyHostToDevice);
16 int block = 4;
17 int grid = (n + block - 1) / block; // aufrunden → 3 Blöcke
18 vecAdd<<<grid, block>>>(d_a, d_b, d_c, n);
19 cudaMemcpy(h_c, d_c, n * sizeof(float), cudaMemcpyDeviceToHost);
20 cudaFree(d_a); cudaFree(d_b); cudaFree(d_c);
21}
Schritt 1: Zeile 9

Host-Daten anlegen

Die Eingaben liegen zunächst nur im Arbeitsspeicher des Hosts (CPU). Die GPU kann darauf nicht direkt zugreifen.

globale Lesezugriffe
0
globale Schreibzugriffe
0
🧠 Host (RAM)
h_a
7
0
4
0
7
4
4
1
2
5
h_b
9
3
2
0
2
5
0
9
6
6
h_c
?
?
?
?
?
?
?
?
?
?
═══ PCIe / NVLink ═══
🟩 Device (VRAM)
d_anicht angelegt
d_bnicht angelegt
d_cnicht angelegt
Grid <<<3, 4>>>
Block 0
0
1
2
3
Block 1
4
5
6
7
Block 2
8
9
10
11