在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/

10-11 17:20