CUDA global函数是否自动递增线程编号?是否需要手动累加ix、iy?
CUDA核函数线程索引问题解答
- CUDA 不会自动完成线程索引的递增操作,每个线程的
threadIdx、blockIdx值在核函数启动时就已经固定,每个线程独立执行核函数的代码,不会自动修改你自定义的ix、iy索引变量。 - 你当前代码中手动递增
ix、iy的逻辑存在错误:
你同时对两个维度的索引加1,只会遍历到图像中
ix == iy的对角线像素,其余绝大多数像素都不会被处理,完全不符合逐像素处理灰度图的需求。
如果你的需求是当启动线程数小于总像素数时,让单个线程处理多个像素(即grid-stride循环写法),正确的实现参考如下:
__device__ float gpuFrameResultArray[MEMORYFRAME][HEIGHT][WIDTH]; __global__ void GrayVideoToArrays(float frameReading[HEIGHT][WIDTH], float frameResultArray[HEIGHT][WIDTH], int initialframeCount){ int ix = threadIdx.x + blockIdx.x * blockDim.x; int iy = threadIdx.y + blockIdx.y * blockDim.y; // 定义两个维度各自的步长 const int stride_x = gridDim.x * blockDim.x; const int stride_y = gridDim.y * blockDim.y; // 两个维度分开遍历 for(; ix < HEIGHT; ix += stride_x){ for(; iy < WIDTH; iy += stride_y){ gpuFrameResultArray[initialframeCount][ix][iy] = frameReading[ix][iy]; frameResultArray[ix][iy] = gpuFrameResultArray[initialframeCount][ix][iy]; } } }
- 你原有代码中的
__syncthreads()调用存在严重问题:
__syncthreads()要求同一个线程块内的所有线程都执行到这条指令才会继续向下执行,你把它放在循环内部,当部分线程因为索引超出边界退出循环后,剩余线程会永远等不到已退出的线程到达同步点,直接导致核函数死锁。你的场景只是逐像素拷贝,不需要线程间同步,直接删掉这个调用即可。
内容的提问来源于stack exchange,提问作者Elif Kantar
相关产品推荐
相关产品推荐

