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 = 102465536 ブロック x 128 スレッドを実行しようとしており、最大グリッド ディメンション (コンピューティング機能 1.x および 2.x の GPU では 65535 ブロック、3.x については不明) を超えています。

より多くのスレッドを実行する必要がある場合は、ブロック サイズを大きくするか (既に試してみて、ある程度の効果が得られました)、2D/3D グリッドを使用できます (3D は、コンピューティング機能が 2.0 以上のデバイスでのみ使用できます)。

于 2012-08-25T18:36:30.860 に答える