2012-04-30 4 views
3
내 CUDA 코드가

CUDA GPU를 CPU

내 바탕 화면 구성이 I7 2600S 내 CPU의 코드보다 느리게 실행 왜 문제 파악을 데

, 지포스 560ti

보다 느린 내 코드는 다음과 같다 :

int** kernel_shiftSeam(int **MCEnergyMat, int **newE, int *seam, int width, int height,  int direction) 
{ 
//time measurement 
float elapsed_time_ms = 0; 
cudaEvent_t start, stop; //threads per block 

dim3 threads(16,16); 
//blocks 
dim3 blocks((width+threads.x-1)/threads.x, (height+threads.y-1)/threads.y); 

int *device_Seam; 

int *host_Seam; 

int seamSize; 
if(direction == 1) 
{ 
    seamSize = height*sizeof(int); 
    host_Seam = (int*)malloc(seamSize); 
    for(int i=0;i<height;i++) 
    host_Seam[i] = seam[i]; 
} 
else 
{ 
    seamSize = width*sizeof(int); 
    host_Seam = (int*)malloc(seamSize); 
    for(int i=0;i<width;i++) 
     host_Seam[i] = seam[i]; 
} 

cudaMalloc((void**)&device_Seam, seamSize); 
cudaMemcpy(device_Seam, host_Seam, seamSize, cudaMemcpyHostToDevice); 

global_host_MC = MCEnergyMat; 
new_host_MC = newE; 

//copy host array to device 
cudaMemcpy(global_MC, global_MC2, sizeof(int*)*width, cudaMemcpyHostToDevice); 
    for(int i=0;i<width;i++) 
     cudaMemcpy(global_MC2[i], global_host_MC[i], sizeof(int)*height, cudaMemcpyHostToDevice); 

cudaMemcpy(new_MC, new_MC2, sizeof(int*)*width, cudaMemcpyHostToDevice); 
    for(int i=0;i<width;i++) 
     cudaMemcpy(new_MC2[i], new_host_MC[i], sizeof(int)*height, cudaMemcpyHostToDevice); 


cudaEventCreate(&start); 
cudaEventCreate(&stop); 
cudaEventRecord(start, 0); 

//do some operations on the 2d matrix 
gpu_shiftSeam<<< blocks,threads >>>(global_MC, new_MC, device_Seam, width, height); 

//measure end time for cpu calcuations 
cudaEventRecord(stop, 0); 
cudaEventSynchronize(stop); 
cudaEventElapsedTime(&elapsed_time_ms, start, stop); 

execTime += elapsed_time_ms; 

//copy out the data back to host (RESULT) 
for(int i=0;i<width;i++) 
{ 
    cudaMemcpy(newE[i], new_MC2[i], sizeof(int)*height, cudaMemcpyDeviceToHost); 
} 

return newE; 
} 

나는 800 번을 반복하고 나는 추적 결과를 얻었다 :

GPU 계산 시간합니다 (gpu_shiftseam 부분) : 1176ms을 617,451,515,전체 프로그램 실행 시간 : 22S

CPU 계산 시간 (gpu_shiftseam 그러나 호스트에서 같은 동작을) : 12S

은 분명히 GPU 계산 시간이 CPU에 하나보다 훨씬 짧은 : 전체 프로그램 실행 시간을 12522ms ,하지만 어떤 이유로 gpu에 대한 전체 프로그램 실행 시간이 더 길어도 사람이 이유를 알고 있습니까? 스레드/블록 수를 할당하기 때문에 이 잘못 되었습니까? 아니면 "느린"장치에서 메모리를 할당하는 것입니까?

고맙습니다.

+2

시간 이동 위치를 볼 수 있도록 타이머를 움직이거나 더 많은 타이머를 만드십시오. 어쩌면 시간이 cudaMemcpy() 호출에서 사용됩니다. –

+0

만약 당신이 말한 것처럼 cudaMemcpy() 호출에서 시간이 사용된다면? 그 기능을 사용하여 많은 시간을 소비하는 것은 불가피한가요? 왜냐하면 나는 theres를 cudaMemcpy()의 대안으로 생각하지 않기 때문입니다. –

+0

최적화하기 전에 kernel_shiftSeam의 하위 섹션을 시간을내어 사용하거나 프로파일 러 (병렬 Nsight, CUDA 프로파일 러, NVIDIA Visual Profiler) 중 하나를 사용하십시오. –

답변

2

내 경험으로 메모리 액세스 속도가 느려질 수 있습니다.

얼마나 많은 시간을 보냈는지 확인하려면 배열 복사본을 프로파일하십시오. 상당한 양의 코드 인 경우 코드 최적화를 시도하십시오. for 루프 내부를 복사하는 대신 sizeof(int *) * height * width을 직접 복사 할 수 있는지 확인하십시오. memcpy를 호출하는 시간을 줄이면 도움이됩니다.

cudaMemcpy(global_MC, global_MC2, sizeof(int*)*width, cudaMemcpyHostToDevice); 
cudaMemcpy(global_MC2, global_host_MC, sizeof(int)*height*width,cudaMemcpyHostToDevice); 
+0

주셔서 감사합니다! sizeof (int *) * height * width를 복사하면 시간이 단축되지만 가끔씩 올바른 출력 만 생성됩니다. for 루프없이 memcpy를 수행하는 또 다른 방법이 있습니까? –

+2

경우에 따라 올바른 출력이 생성되는 경우 동기화 문제가 발생할 가능성이 높습니다. – kerem

0

나는 비슷한 경험을했고 cudaMemcpy가없는 동안 cudaMalloc가 병목 것을 발견했다. 내 장치에서는 16MB 할당에 160 밀리 초가 걸렸습니다. 그러나 CUDA 메모리 할당은 실제 계산 전에 수행 할 수 있습니다 (예 : 다른 함수 호출). 따라서, 메모리 할당 시간은 스피드 업 계산에서 cudaMemcpy 연산을 포함 할지라도 전체 성능 측정치, 예컨대 스피드 업으로부터 제거 될 수있다.

관련 문제