当编写一个内核时,它将对一维数组的一个元素进行操作,具有可以从 2 到 100 百万的大维度 N,或者在具有相同维度 N 的多个一维数组的一个具有相同索引的元素上,什么是计算内核网格大小的最佳方法吗?特别是,以下是最佳方式:
CPU部分:
cudaSetDevice(device);
cudaGetDeviceProperties(&deviceProp, device);
max_threads_per_block = deviceProp.maxThreadsPerBlock;
number_CUDA_cores = _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor) * deviceProp.multiProcessorCount;
GPU部分:
if (N <= number_CUDA_cores) {
blocks = N;
threads_per_block = 1;
}
else {
blocks = number_CUDA_cores;
threads_per_block = (N + number_CUDA_cores - 1) / number_CUDA_cores;
if (threads_per_block > max_threads_per_block) {
blocks = (N + max_threads_per_block - 1) / max_threads_per_block;
threads_per_block = max_threads_per_block;
}
}
kernel<<<blocks, threads_per_block>>>( ..... )
同样,在 K20 或 K20x 上,这必须适用于从 2 到 100 百万的 N 大小,甚至更好。
如果出现以下情况,答案是否会有所不同:
1)内核大多是直接代码
2) 内核有许多 if 语句,它们在执行时会出现分歧(这就是为什么我试图让块尽可能小)。