2016-07-22 9 views
0

Ich arbeite derzeit an einem Cuda-Code, der einen einfachen Unterschied Pixel für Pixel von zwei Bildern (Größe: 2560x1706 px) berechnet, um die Ausführungszeit von CPU und GPU zu vergleichen.Seltsame Cudamemcpy Ausführungszeit

Ich realisiere eine "for" -Schleife von 1000 Iterationen meines Kernels, um eine signifikantere Ausführungszeit zu haben, und ich führe cudaMemcpy (von Gerät zu Host) direkt nach der Schleife durch, um die berechneten Daten abzurufen.

Dennoch dauerte die Ausführungszeit dieses cudaMemcpy 2800 ms, was höher ist als erwartet. Ich habe mich gerade gefragt, warum ich so ein Ergebnis erhalte.

Hier ist mein Kernel-Code:

__global__ void diff (unsigned char *data1 ,unsigned char *data2, int *data_res) 
{ 
    int v = threadIdx.x + blockIdx.x*blockDim.x; 

    if (v < N) 
    { 
    data_res[v] = (int) data2[v] - (int) data1[v]; 
    } 
} 

Hier werden die Kernel-Anrufe ist:

cudaProfilerStart(); 

    // Cuda allocation 
    cudaMalloc((void**)&dev_data1, N*sizeof(unsigned char)); 
    cudaMalloc((void**)&dev_data2, N*sizeof(unsigned char)); 
    cudaMalloc((void**)&dev_data_res, N*sizeof(int)); 

    // Cuda memory copy 
    cudaMemcpy(dev_data1, img1->data, N*sizeof(unsigned char), cudaMemcpyHostToDevice); 
    cudaMemcpy(dev_data2, img2->data, N*sizeof(unsigned char), cudaMemcpyHostToDevice); 
    cudaMemcpy(dev_data_res, imgresult->data, N*sizeof(int), cudaMemcpyHostToDevice); 

    //Simulate nb_loops images 
    for(int m = 0; m < nb_loops ; m++) 
    { 
     diff<<<blck_nb, thrd_nb>>>(dev_data1, dev_data2, dev_data_res); 
     //printf("%4d", m); 
    } 


    printf("WAITING FOR MEMCPY...\n"); 

    clock_t begin = clock(), diff; 

    cudaMemcpy(imgresult_data, dev_data_res, N*sizeof(int), cudaMemcpyDeviceToHost); 

    diff = clock() - begin; 
    float msec = diff*1000/CLOCKS_PER_SEC; 
    printf("\t \nTime of the MEMCPY : %2.3f ms\n", msec); 

    printf("MEMCPY DEVICE TO HOST OK!\n"); 

    cudaProfilerStop(); 

Und hier ist der Screenshot der Ergebnisse der Ausführungszeit:

screenshot

+0

Kernel-Starts sind asynchron, Ihr Timing ist also falsch. – talonmies

Antwort

2

CUDA-Kernel-Starts sind asynchron und cudaMemcpy ist ein blockierender Anruf. Also, was Sie memcpy Zeit nennen, ist wirklich Kernel-Ausführung + memcpy tiime. Ändern Sie Ihren Code wie folgt:

... 
for(int m = 0; m < nb_loops ; m++) 
{ 
    diff<<<blck_nb, thrd_nb>>>(dev_data1, dev_data2, dev_data_res); 
    //printf("%4d", m); 
} 

cudaDeviceSynchronize(); 
printf("WAITING FOR MEMCPY...\n"); 
.... 

und dieses Timing sollte korrekt sein.

+0

Dies gab mir effektiv die richtige cudaMemcpy Ausführungszeit nach der Assertion von cudaDeviceSynchronize(). Allerdings verwende ich eine NVIDIA GT720 und die Ausführungszeit der GPU ist nur 6 mal schneller als die CPU-Ausführungszeit. Was denkst du darüber ? Sollte nicht etwa 100 Mal schneller sein? Scheint es konsistent? Danke für Ihre Hilfe. – Flow

+0

@Flow: Sie führen Ihren Code auf dem langsamsten fast aktuellen GPU-Modell, das NVIDIA produziert. Sechs Mal schneller scheint völlig vernünftig. Hunderte Male nicht. – talonmies