我无法弄清楚为什么我的cuda代码比我的cpu代码运行慢
我的桌面配置是i7 2600S,geforce 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 总计划运行时间:22秒
CPU 计算时间(与gpu_shiftseam相同的操作,但在主机上):12522ms 总计划运行时间:12秒
显然,GPU计算时间比CPU上的计算时间短,但是 由于某种原因,gpu的总程序运行时间要长得多 谁知道为什么?是因为我分配的线程/块的数量 是不正确的?或者在设备上分配内存是否“缓慢”?
非常感谢!
答案 0 :(得分: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);
答案 1 :(得分:0)
我有类似的经历,发现cudaMalloc是瓶颈而cudaMemcpy不是。在我的设备中,我记得16 MB的分配花费了160毫秒。然而,CUDA存储器分配可以在实际计算之前完成,例如,通过另一个函数调用。因此,可以从整体性能测量中去除存储器分配时间,例如加速,尽管我将在加速计算中包括cudaMemcpy操作。