0

Visual Studio 2010 での画像処理のために cuda でアルゴリズムを作成しています。私のコーディングでは、cuda のスレッドとブロックでの作業に問題がありました。C と CUDA のサンプル コードを以下に示します。C コードは問題なく動作しますが、CUDA コードは正確には動作しません。私のCコード

void checkGpuBlockValue(unsigned int *a,unsigned int *b,int length)
{
    for(int i=0;i<length;i++){
        b[i]=a[i]+i;
    }

}

int main()
{
    const int range=1000;
    unsigned int *a=new unsigned int[range];
    unsigned int *b=new unsigned int[range];

    for(int i=0;i<range;i++)
    {
        a[i]=i;
    }

checkGpuBlockValue(a,b,range);

for(int j=0;j<range;j++)
    {
        cout<<"b["<<j<<"] = "<<b[j]<<std::endl;
    }
}

出力 =

OutPut :
b[0] = 0
b[1] = 2
b[2] = 4
b[3] = 6
b[4] = 8
.
.
.
.
.

b[996] = 1992
b[997] = 1994
b[998] = 1996
b[999] = 1998

これはうまくいきます。

私のCUDAコード(うまく機能しない)は;

__global__
void checkGpuBlockValue(unsigned int *a,unsigned int *b,int length)
{
    unsigned int i = (blockIdx.x * blockDim.x) + threadIdx.x;

    if(i<length){
        b[i]=a[i]+i;
    }

}

int main()
{
    const int range=1000;
    unsigned int *a=new unsigned int[range];
    unsigned int *b=new unsigned int[range];

    unsigned int *dev_a;
    unsigned int *dev_b;

    for(int i=0;i<range;i++)
    {
        a[i]=i;
    }

    cudaMalloc( (void**)&dev_a, range* sizeof(unsigned int));
    cudaMalloc( (void**)&dev_b, range* sizeof(unsigned int));

    cudaMemcpy(dev_a, a, range, cudaMemcpyHostToDevice);
    cudaMemcpy(dev_b, a, range, cudaMemcpyHostToDevice);

    static const int BLOCK_WIDTH = 8;       

    //1024 is the maximum number of threads per block for modern GPUs.

    int x = static_cast<int>(ceilf(static_cast<float>(range) / BLOCK_WIDTH));


    const dim3 grid (x,1);                              
    const dim3 block(BLOCK_WIDTH,1);    

    checkGpuBlockValue<<<grid,block>>>(dev_a,dev_b,range);
    cudaDeviceSynchronize();

    cudaMemcpy(b, dev_b, range, cudaMemcpyDeviceToHost);


    for(int j=0;j<range;j++)
    {
        cout<<"b["<<j<<"] = "<<b[j]<<std::endl;
    }

    cudaFree(dev_a);
    cudaFree(dev_b);
}

出力は:

Out Put =
b[0] = 0
b[1] = 2
b[2] = 4
b[3] = 6
.
.
.
.
.
b[242] = 484
b[243] = 486
b[244] = 488
b[245] = 490
b[246] = 492
b[247] = 494
b[248] = 496
b[249] = 498
b[250] = 3452816845
b[251] = 3452816845
b[252] = 3452816845
b[253] = 3452816845
b[254] = 3452816845
b[255] = 3452816845
b[256] = 3452816845
.
.
.
.
.
.
b[996] = 3452816845
b[997] = 3452816845
b[998] = 3452816845
b[999] = 3452816845

私のコードでは、int * aに0から1000の値を入力し、その* aに0から1000の値を追加し、結果をint * bに格納しています。したがって、私のコードは 0 から 249 (最大 250) のループではうまく機能しますが、250 を超えると間違った値が返されます。それで、私はここで何が間違っていますか?私に提案してください。

4

1 に答える 1

1

コードを見るだけで、問題はこれらの行にあるように見えます

 cudaMemcpy(dev_a, a, range, cudaMemcpyHostToDevice);
 cudaMemcpy(dev_b, a, range, cudaMemcpyHostToDevice);
 ....
 ....
 cudaMemcpy(b, dev_b, range, cudaMemcpyDeviceToHost);

する必要があります

 cudaMemcpy(dev_a, a, range* sizeof(unsigned int), cudaMemcpyHostToDevice);
 cudaMemcpy(dev_b, a, range* sizeof(unsigned int), cudaMemcpyHostToDevice);
 ....
 ....
 cudaMemcpy(b, dev_b, range * sizeof(unsigned int), cudaMemcpyDeviceToHost);

コードを変更して、期待どおりに動作することを確認しました。ただし、適切なプログラミングの実践として、適切なエラー チェックを行うことを強くお勧めします。

于 2013-10-22T06:25:01.593 に答える