基本的CUDA指针/数组内存分配和使用

时间:2013-07-04 15:01:08

标签: c++ cuda

我上周开始使用CUDA,因为我必须将现有的c ++程序转换为cuda用于我的研究。

这是CUDA by Example本书的基本示例,我建议任何想要学习CUDA的人!

有人可以解释如何使用'dev_c'指定GPU内存,这是一个空指针吗?

HANDLE_ERROR( cudaMalloc( (void**)&dev_c, N * sizeof(int) ) );

然后,在调用函数'add'时不传递任何'dev_c'值,而是将* c视为全局函数中的数组并从函数内写入?当它未在任何地方定义为数组时,为什么这可能呢?

add<<<N,1>>>( dev_a, dev_b, dev_c );

最后,在执行以下添加时,c [0],c [1]等术语的确切位置是什么?

c[tid] = a[tid] + b[tid];

我希望我能很好地解释自己,但随时可以提出任何后续问题。 C和CUDA的新手很好:D

以下全部代码:

#include "book.h"

#define N   1000

__global__ void add( int *a, int *b, int *c ) {
    int tid = blockIdx.x;    // this thread handles the data at its thread id
    if (tid < N)
        c[tid] = a[tid] + b[tid];
}

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

    // allocate the memory on the 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) ) );

    // fill the arrays 'a' and 'b' on the CPU
    for (int i=0; i<N; i++) {
        a[i] = -i;
        b[i] = i * i;
    }

    // copy the arrays 'a' and 'b' to the GPU
    HANDLE_ERROR( cudaMemcpy( dev_a, a, N * sizeof(int),
                                cudaMemcpyHostToDevice ) );
    HANDLE_ERROR( cudaMemcpy( dev_b, b, N * sizeof(int),
                                cudaMemcpyHostToDevice ) );

    add<<<N,1>>>( 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 ) );

    // display the results
    for (int i=0; i<N; i++) {
        printf( "%d + %d = %d\n", a[i], b[i], c[i] );
    }

    // free the memory allocated on the GPU
    HANDLE_ERROR( cudaFree( dev_a ) );
    HANDLE_ERROR( cudaFree( dev_b ) );
    HANDLE_ERROR( cudaFree( dev_c ) );

    return 0;
}

谢谢!

1 个答案:

答案 0 :(得分:1)

在SO问题的空间里教授CUDA是不可能的。我会尝试回答你的问题,但你应该利用一些资源。如果你不了解C或C ++会特别困难,因为典型的CUDA编程取决于那些。

您可能需要参加一些介绍性网络研讨会here,例如:

使用CUDA C进行GPU计算 - 简介(2010) 使用CUDA C概述GPU计算的基础知识将通过代码示例的演练来说明。无需先前的GPU计算经验

使用CUDA C进行GPU计算 - 高级1(2010) 第一级优化技术,如全局内存优化和处理器利用率。将使用实际代码示例来说明概念

现在回答你的问题:

  

有人可以解释如何使用&#39; dev_c&#39;分配GPU内存。这是一个空指针?

dev_c以空指针开头。但cudaMalloc函数allocates GPU memory根据传递给它的大小,建立指向该分配的指针,并将该指针存储到dev_c指针中。它可以这样做,因为我们是passing the address of dev_c,而不是实际指针本身。

  

然后,不要传递任何&#39; dev_c&#39;调用函数时的值&#39;添加&#39;但是将* c视为全局函数中的数组并从函数内写入?当它未在任何地方定义为数组时,为什么这可能呢?

在C中,指针(dev_c是什么)可以指向单个值或值数组。指针本身不包含有关它指向的数据量的信息。由于dev_c存储结果,并且已经由前面的cudaMalloc函数正确初始化,我们可以使用它来存储内核中的操作结果。 dev_c实际指向int的一个存储区域,其大小由N * sizeof(int)给出,传递给前面的cudaMalloc函数。< / p>

  

最后,在执行以下添加时,c [0],c [1]等术语的确切位置是什么?

在c中,当我们有这样的函数定义时:

void my_function(int *c){...}

这表示函数中的语句可以引用名为c的变量,就好像它是指向一个或多个int值的指针(单个值或值数组,从...开始存储c)指向的位置。

当我们调用该函数时,我们可以使用名为参数的其他变量,对于名为c的函数参数,如下所示:

int my_ints[32];
my_function(my_ints);

现在,在my_function内,无论引用参数 c,它都将使用(指针){给出的参数值{1}}。

相同的概念适用于cuda函数(内核)及其参数和参数。