2016-05-09 19 views
1

Ich habe NVS 5400M und ich versuche, zuverlässige Zeitmessung Ergebnisse für Cuda Addition auf Matrix (Instanz 1000 x 1000) zu bekommen.Cuda Kernel Zeitmessung mit CudaEventElapsedTime

__global__ void MatAdd(int** A, int** B, int** C) { 
int i = threadIdx.x; 
int j = threadIdx.y; 
C[i][j] = A[i][j] + B[i][j]; } 

Und ich mache Messung wie:

int numBlocks = 1; 
dim3 threadsPerBlock(1000, 1000); 

float time; 
cudaEvent_t start, stop; 
cudaEventCreate(&start); 
cudaEventCreate(&stop); 
cudaEventRecord(start, 0); 

MatAdd <<<numBlocks, threadsPerBlock>>>(pA, pB, pC); 

cudaEventRecord(stop, 0); 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&time, start, stop); 

cout << setprecision(10) << "GPU Time [ms] " << time << endl; 

und das Ergebnis ist: ,001504000043 ms, die relativ klein ist. Meine Frage ist, mache ich es richtig?

Antwort

1

Ihr Timing ist korrekt, aber Ihre Verwendung von CUDA ist im Allgemeinen nicht.

Dies ist illegal:

dim3 threadsPerBlock(1000, 1000); 

CUDA Kerne werden auf maximal 1024 Fäden pro Block begrenzt, aber Sie sind 1000x1000 = 1.000.000 Threads pro Block anfordert.

Als Ergebnis Ihr Kernel startet nicht tatsächlich:

MatAdd <<<numBlocks, threadsPerBlock>>>(pA, pB, pC); 

Und so ist die gemessene Zeit recht kurz.

Sie sollten proper cuda error checking verwenden und Ihre Tests mit cuda-memcheck ausführen, um sicherzustellen, dass keine Laufzeitfehler gemeldet werden (ich nehme an, dass Sie die Fehler, die aus Ihrem Code gemeldet werden, nicht kennen sie.)

Da Sie nicht einen vollständigen Code gezeigt haben, werde ich nicht versuchen, alle anderen Probleme zu identifizieren, die vorhanden sein können, aber Ihr Kernel-Code müsste re-faktorisiert werden, um eine zu behandeln 1000x1000-Array korrekt zu übertragen und Doppelzeiger (z. B. int** A) an Kernel zu übergeben, ist erheblich schwieriger als ein einzelner Zeiger oder ein "flacher" Array.

+0

Nach der Überprüfung von cudError_t habe ich die Meldung erhalten: sync kernel error: ungültiges Konfigurationsargument. Vielen Dank! – azet52

+0

@Edit: Ich habe geändert in 'dim3 threadsPerBlock (32, 32)' und der tatsächliche Code ist: 'int ** A = create_random_matrix (1000);' 'int ** pA = initialize_matrix (1000); ' ' cudaMalloc ((void **) pA, (1000 * 1000) * sizeof (int)); ' ' cudaMemcpy (pA, A, (1000 * 1000) * sizeof (int), cudaMemcpyHostToDevice) ' das gleiche für B & C und danach 'MatAdd <<< numBlocks, threadsPerBlock >>> (pA, pB, pC);' 'cudaMemcpy (C, pC, (1000 * 1000) * sizeof (int), cudaMemcpyDeviceToHost) ; ' und empfangen: ungültiges Argument und ungültiger Speicherzugriff wurde ausgelöst – azet52

+0

Der Zugriff auf den ungültigen Speicher erfolgt, weil Sie nicht verstehen, wie Sie Argumente von Doppelzeigern korrekt an Kerne verwalten. Es wird eine tiefe Kopie erfordern. Der Einfachheit halber würde ich vorschlagen, Ihre Arrays so abzuflachen, dass sie mit einem einzigen Index referenziert werden können. Wenn Sie Hilfe mit einem Code benötigen, den Sie nicht angezeigt haben, und einem neuen Problem, schlage ich vor, eine neue Frage zu stellen. –