【发布时间】:2013-06-15 00:51:02
【问题描述】:
我正在处理一些 cuda tutorial 将 RGBA 图片转换为灰度。
但我不明白为什么更改 blockSize 和 gridSize 会使时间缩短 X33。
__global__
void rgba_to_greyscale(const uchar4* const rgbaImage,
unsigned char* const greyImage,
int numRows, int numCols)
{
int i = blockIdx.x*numCols + threadIdx.x;
float channelSum = .299f * rgbaImage[i].x + .587f * rgbaImage[i].y + .114f * rgbaImage[i].z;
greyImage[i]= channelSum;
}
void your_rgba_to_greyscale(const uchar4 * const h_rgbaImage, uchar4 * const d_rgbaImage,
unsigned char* const d_greyImage, size_t numRows, size_t numCols)
{
const dim3 blockSize(numCols, 1, 1);
const dim3 gridSize(numRows, 1 , 1);
rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage, numRows, numCols);
cudaDeviceSynchronize(); checkCudaErrors(cudaGetLastError());
}
当我如上设置时:
const dim3 blockSize(numCols, 1, 1);
const dim3 gridSize(numRows, 1 , 1);
我收到Your code executed in 0.030304 ms
当我设置时:
const dim3 blockSize(1, 1, 1);
const dim3 gridSize(numRows, numCols , 1);
并更新线程函数以使用新索引:
int i = blockIdx.x*numCols + blockIdx.y;
我收到Your code executed in 0.995456 ms。
- 我希望它是相反的,因为 gpu 可以计算所有 第二个网格分裂上的像素分别是否与 缓存一致性问题?为什么我会得到这些结果?
- 从理论上讲,这个问题的最佳网格和块大小是多少?是否可以在运行时计算?
仅供参考:
numRows = 313 numCols =557
技术性能:
#uname -a && /usr/bin/nvidia-settings -v
Linux ip-10-16-23-92 3.2.0-39-virtual #62-Ubuntu SMP Thu Feb 28 00:48:27 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
nvidia-settings: version 304.54 (buildmeister@swio-display-x86-rhel47-11)
【问题讨论】:
-
快速回答是 NVIDIA GPU 在称为 warp 的线程组中调度、获取、分派和执行指令。对于计算能力为 1.* - 3.* 的设备,warp 大小为 32。如果您启动仅包含 1 个线程的块,硬件会将块分为 1 个 warp,其中包括 1 个活动线程和 32 个非活动线程。数学管道和 LSU 的执行效率将是 1/32(你看是 32X)。