在Linux上使用CUDA4.2和驱动程序295.41时,我看到了一个非常有趣的行为。
代码本身只不过是寻找随机矩阵的最大值,并将位置标记为1。
#include <stdio.h>
#include <stdlib.h>
const int MAX = 8;
static __global__ void position(int* d, int len) {
int idx = threadIdx.x + blockIdx.x*blockDim.x;
if (idx < len)
d[idx] = (d[idx] == MAX) ? 1 : 0;
}
int main(int argc, const char** argv) {
int colNum = 16*512, rowNum = 1024;
int len = rowNum * colNum;
int* h = (int*)malloc(len*sizeof(int));
int* d = NULL;
cudaMalloc((void**)&d, len*sizeof(int));
// get a random matrix
for (int i = 0; i < len; i++) {
h[i] = rand()%(MAX+1);
}
// launch kernel
int threads = 128;
cudaMemcpy(d, h, len*sizeof(int), cudaMemcpyHostToDevice);
position<<<(len-1)/threads+1, threads>>>(d, len);
cudaMemcpy(h, d, len*sizeof(int), cudaMemcpyDeviceToHost);
cudaFree(d);
free(h);
return 0;
}
当我设置rowNum=1024时,代码根本不工作,就好像内核从未启动过一样。
如果rowNum=1023,一切正常。
这个rowNum值与块大小(在这个例子中是128)有某种关系,如果我将块大小更改为512,则行为发生在rowNum=4095和4096之间。
我不太确定这是虫子还是我漏掉了什么?
最佳答案
调用CUDA函数后,您应该始终检查是否有错误。例如,在您的代码中,invalid configuration argument
错误发生在内核启动期间。
这通常意味着栅格或块尺寸不有效。
在colNum = 16*512, rowNum = 1024
中,您尝试运行65536个块x 128线程,超过最大网格维度(对于计算能力为1×2和2 x的GPU是65535个块,不确定3。x)。
如果需要运行更多的线程,可以增加块大小(您已经尝试过了,它已经产生了一些效果)或使用2D/3D网格(3D仅适用于具有计算能力2.0或更高版本的设备)。
关于linux - 使用CUDA 4.2和驱动程序295.41的非常有趣的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12124377/