0

在 Linux 上使用 CUDA 4.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 之间。

我不太确定这是一个错误还是我错过了什么?

4

1 回答 1

1

调用 CUDA 函数后,您应该始终检查错误。例如,在您的代码中,invalid configuration argument错误发生在内核启动期间。

这通常意味着网格或块尺寸无效。

colNum = 16*512, rowNum = 1024您尝试运行 65536 个块 x 128 个线程时,超过了最大网格尺寸(对于具有计算能力 1.x 和 2.x 的 GPU,它是 65535 个块,不确定 3.x)。

如果您需要运行更多线程,您可以增加块大小(您已经尝试过并且它产生了一些效果)或使用 2D/3D 网格(3D 仅适用于具有 2.0 或更高计算能力的设备)。

于 2012-08-25T18:36:30.860 回答