2

以下のコードは、2つのベクトルaとbの内積を計算します。正しい結果は8192です。初めて実行したときの結果は正しいです。次に、2回目に実行すると、結果は前の結果+8192などになります。

1st iteration: result = 8192
2nd iteration: result = 8192 + 8192
3rd iteration: result = 8192 + 8192 
and so on.

画面に印刷して確認しましたが、デバイス変数dev_cが解放されていません。さらに書き込むと、合計のようなものが発生し、結果は前の値に新しい値が書き込まれます。それはatomicAdd()操作で何かできると思いますが、それでもcudaFree(dev_c)は結局それを消去するはずです。

#define N 8192
#define THREADS_PER_BLOCK 512
#define NUMBER_OF_BLOCKS (N/THREADS_PER_BLOCK)
#include <stdio.h>


__global__ void dot( int *a, int *b, int *c ) {

    __shared__ int temp[THREADS_PER_BLOCK];

    int index = threadIdx.x + blockIdx.x * blockDim.x;

    temp[threadIdx.x] = a[index] * b[index];

    __syncthreads();

    if( 0 == threadIdx.x ) {

        int sum = 0;
        for( int i= 0; i< THREADS_PER_BLOCK; i++ ){
        sum += temp[i];
        }
        atomicAdd(c,sum);
    }
}

    int main( void ) {

        int *a, *b, *c;
        int *dev_a, *dev_b, *dev_c; 
        int size = N * sizeof( int); 

        cudaMalloc( (void**)&dev_a, size );
        cudaMalloc( (void**)&dev_b, size );
        cudaMalloc( (void**)&dev_c, sizeof(int));

        a = (int*)malloc(size);
        b = (int*)malloc(size);
        c = (int*)malloc(sizeof(int));

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

        cudaMemcpy( dev_a, a, size, cudaMemcpyHostToDevice);
        cudaMemcpy( dev_b, b, size, cudaMemcpyHostToDevice);

        dot<<< N/THREADS_PER_BLOCK,THREADS_PER_BLOCK>>>( dev_a, dev_b, dev_c);

        cudaMemcpy( c, dev_c, sizeof(int) , cudaMemcpyDeviceToHost);

        printf("Dot product = %d\n", *c);

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

        free(a); 
        free(b); 
        free(c);

        return 0;

    }
4

2 に答える 2

9

cudaFree は何も消去しません。メモリをプールに戻して再割り当てするだけです。cudaMalloc は割り当てられたメモリの値を保証しません。一貫した結果を得るには、プログラムが使用するメモリ (グローバルと共有の両方) を初期化する必要があります。ちなみに、 malloc と freeについても同じことが言えます。

于 2012-10-27T13:39:23.410 に答える
5

cudaMalloc()のドキュメントから;

メモリはクリアされません。

これは、dev_c が初期化されていないことを意味atomicAdd(c,sum);し、返された位置でたまたまメモリに格納されている任意のランダムな値に追加されます。

于 2012-10-27T13:39:28.900 に答える