0

私は CUDA を学習しようとしていますが、次のコードは N<= 16384 の値では問題なく動作しますが、それより大きい値では失敗します (コードの最後の合計チェックは失敗し、i のインデックス値の c 値は常に 0 です)。 =16384)。

#include<iostream>
#include"cuda_runtime.h"
#include"../cuda_be/book.h"

#define N (16384)

__global__ void add(int *a,int *b,int *c)
{
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    if(tid<N)
    {
        c[tid] = a[tid] + b[tid];
        tid += blockDim.x * gridDim.x;
    }
}

int main()
{
    int a[N],b[N],c[N];
    int *dev_a,*dev_b,*dev_c;

    //allocate mem on gpu
    HANDLE_ERROR(cudaMalloc((void**)&dev_a,N*sizeof(int)));
    HANDLE_ERROR(cudaMalloc((void**)&dev_b,N*sizeof(int)));
    HANDLE_ERROR(cudaMalloc((void**)&dev_c,N*sizeof(int)));

    for(int i=0;i<N;i++)
    {
        a[i] = -i;
        b[i] = i*i;
    }

    HANDLE_ERROR(cudaMemcpy(dev_a,a,N*sizeof(int),cudaMemcpyHostToDevice));
    HANDLE_ERROR(cudaMemcpy(dev_b,b,N*sizeof(int),cudaMemcpyHostToDevice));
    system("PAUSE");
    add<<<128,128>>>(dev_a,dev_b,dev_c);

    //copy the array 'c' back from the gpu to the cpu

    HANDLE_ERROR( cudaMemcpy(c,dev_c,N*sizeof(int),cudaMemcpyDeviceToHost));

    system("PAUSE");
    bool success = true;
    for(int i=0;i<N;i++)
    {
        if((a[i] + b[i]) != c[i])
        {
            printf("Error in %d: %d + %d != %d\n",i,a[i],b[i],c[i]);
            system("PAUSE");
            success = false;
        }

    }

    if(success) printf("We did it!\n");

    cudaFree(dev_a);
    cudaFree(dev_b);
    cudaFree(dev_c);

    return 0;
}

共有メモリ関連の問題だと思いますが、良い説明が思いつきません(知識不足の可能性があります)。16384 より大きい N の値に対して実行する説明と回避策を教えてください。私の GPU の仕様は次のとおりです。

General Info for device 0
Name: GeForce 9600M GT
Compute capability: 1.1
Clock rate: 1250000
Device copy overlap : Enabled
Kernel Execution timeout : Enabled
Mem info for device 0
Total global mem: 536870912
Total const mem: 65536
Max mem pitch: 2147483647
Texture Alignment 256
MP info about device 0
Multiproccessor count: 4
Shared mem per mp: 16384
Registers per mp: 8192
Threads in warp: 32
Max threads per block: 512
Max thread dimensions: (512,512,64)
Max grid dimensions: (65535,65535,1)
4

3 に答える 3

3

あなたはおそらく書くつもりでした

while(tid<N)

いいえ

if(tid<N)
于 2012-09-30T10:34:14.283 に答える
0

N の場合:

#define N (33 * 1024) //value defined in Cuda by Examples

Cuda by Exampleで見つけた同じコードですが、N の値が異なっていました。N の o 値は 33 * 1024 にできないと思います。ブロック数とブロックあたりのスレッド数のパラメーターを変更する必要があります。なぜなら:

add<<<128,128>>>(dev_a,dev_b,dev_c); //16384 threads 

(128 * 128) < (33 * 1024) なのでクラッシュします。

于 2013-03-06T22:26:59.000 に答える
0

共有メモリが不足しているわけではなく、ベクトル配列がデバイスのグローバル メモリにコピーされています。ご覧のとおり、これには必要な 196608 バイト (16384*4*3) よりもはるかに多くの空き容量があります。

問題の理由は、スレッドごとに 1 つの追加操作しか実行していないため、この構造では、tera が指摘したように、ベクトルの最大次元はカーネル起動のブロック * スレッド パラメーターです。修正することで

if(tid<N)

while(tid<N)

コードでは、各スレッドが複数のインデックスに対して追加を実行し、配列全体が考慮されます。

メモリ階層とメモリが置かれるさまざまな場所の詳細については、CUDA ツールキットで提供される CUDA_C_Programming_Guide.pdf のセクション 2.3 と 5.3 を参照してください。

それが役立つことを願っています。

于 2013-02-11T11:15:17.083 に答える