6

CUDAサイトhttp://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#kernelsからサンプルコードをテストしようとしています。

サイズ4の2つの配列AとBを追加し、それを配列Cに格納したいだけです。これまでのところ、次のようになっています。

#include <stdio.h>
#include "util.h"
void print_array(int* array, int size) {
int i;
for (i = 0; i < size; i++) {
    printf("%d ", array[i]);
}
printf("\n");
}

__global__ void VecAdd(int* A, int* B, int* C) {
int i = threadIdx.x;
C[i] = A[i] + B[i];
}

int main(int argc , char **argv) {
int N = 4;
    int i;
int *A = (int *) malloc(N * sizeof(int));
int *B = (int *) malloc(N * sizeof(int));
int *C = (int *) malloc(N * sizeof(int));

for (i = 0; i < N; i++) {
    A[i] = i + 1;
    B[i] = i + 1;
}

print_array(A, N);
print_array(B, N);


VecAdd<<<1, N>>>(A, B, C);
print_array(C, N);
    return 0;
}

C配列(出力の最後の行)が2、4、6、8になることを期待していますが、追加されていないようです。

1 2 3 4
1 2 3 4
0 0 0 0

私は何が欠けていますか?

4

2 に答える 2

4

GPUとの間でメモリを転送する必要があります。

    int *a_GPU, *b_GPU, *c_GPU;
        
    cudaMalloc(&a_GPU, N*sizeof(int));
    cudaMalloc(&b_GPU, N*sizeof(int));
    cudaMalloc(&c_GPU, N*sizeof(int));
        
    cudaMemcpy(a_GPU, A, N*sizeof(int), cudaMemcpyHostToDevice);
    cudaMemcpy(b_GPU, B, N*sizeof(int), cudaMemcpyHostToDevice);

    VecAdd<<<1, N>>>(a_GPU, b_GPU, c_GPU);

    cudaMemcpy(C, c_GPU, N*sizeof(int), cudaMemcpyDeviceToHost);
        
    print_array(C, N);

    cudaFree(a_GPU);
    cudaFree(b_GPU);
    cudaFree(c_GPU);
于 2012-11-21T22:59:02.423 に答える
4

まず、GPUにコピーされるデータを保持するポインターを定義する必要があります。

この例では、配列「a」、「b」、および「c」をからグローバルメモリにコピーしCPUますGPU's

int a[array_size], b[array_size],c[array_size]; // your original arrays
int *a_cuda,*b_cuda,*c_cuda;                    // defining the "cuda" pointers 

各配列が占めるサイズを定義します。

int size = array_size * sizeof(int); // Is the same for the 3 arrays

次に、cudaで使用されるデータにスペースを割り当てます。

Cudaメモリ割り当て

msg_erro[0] = cudaMalloc((void **)&a_cuda,size);
msg_erro[1] = cudaMalloc((void **)&b_cuda,size);
msg_erro[2] = cudaMalloc((void **)&c_cuda,size);

次に、このデータをCPUからGPUにコピーする必要があります。

CPUからGPUにコピー

msg_erro[3] = cudaMemcpy(a_cuda, a,size,cudaMemcpyHostToDevice);
msg_erro[4] = cudaMemcpy(b_cuda, b,size,cudaMemcpyHostToDevice);
msg_erro[5] = cudaMemcpy(c_cuda, c,size,cudaMemcpyHostToDevice);

カーネルを実行します

int blocks = //;
int threads_per_block = //;
VecAdd<<<blocks, threads_per_block>>>(a_cuda, b_cuda, c_cuda);

結果をGPUからCPUにコピーします(この例では配列C)。

msg_erro[6] = cudaMemcpy(c,c_cuda,size,cudaMemcpyDeviceToHost);

空きメモリ:

cudaFree(a_cuda);
cudaFree(b_cuda);
cudaFree(c_cuda);

デバッグの目的で、私は通常、次のように関数のステータスを配列に保存します。

cudaError_t msg_erro[var];

ただし、これは厳密には必要ではありませんが、割り当てまたはメモリ転送中にエラーが発生した場合に時間を節約できます。必要に応じて、上記のコードからすべての'msg_erro[x]='を取り出すことができます。

'msg_erro [x] ='を管理し、エラーが発生した場合は、次のような関数を使用して、これらのエラーを出力できます。

void printErros(cudaError_t *erros,int size)
{
 for(int i = 0; i < size; i++)
      printf("{%d} => %s\n",i ,cudaGetErrorString(erros[i]));
}
于 2012-11-21T23:28:08.423 に答える