自学内容网 自学内容网

Cuda By Example - 1

导言

有兴趣看Cuda By Example这本书的,相信和我一样,都是cuda方面的小白。因此很有必要对Cuda有个粗略的了解。

作者写这边书的时间是2010年,当时cuda的版本是3.0。使用GPGPU做加速运算远不如今日这般火热,因此作者用了整整一章忽悠读者来学并行计算,使用cuda c。目前toolkit的版本已经更新到了12.6。书中的第二章是讲安装开发环境的,基本上过时了,直接去nvidia的网站上看最新的安装指南吧。有一点需要注意,toolkit 的例子放在github,项目文件有可能对应最新的toolkit版本。如果仅仅是为了学习,建议根据例子下载 对应的toolkit的版本。

cuda toolkit 包含了NVIDIA的编译器nvcc,以及运行库。以windows系统为例,Visual C++提供了项目管理和编译主机端代码的责任,而用于GPU的代码,则是通过NVIDIA的编译器编译的。NVIDIA运行库负责跟驱动沟通,其职责包括但不限于将数据和代码指令送到GPU里去。

细节太复杂,我目前也就懂个皮毛,就不多说了,拿出我们刚开始学C语言时的勇气 - 谁一开始在乎程序内部是如何运行的,先弄清楚怎么写代码再说。

那么CUDA C 和标准的C有哪些不一样呢?

首先,CUDA C的代码文件是以cu作为扩展名的。为了区分那些在主机端运行的代码,在GPU上运行的代码都会加上 __globla__ 或者 __device__这样的修饰符。

其次,CUDA C提供了一组函数,用于操作GPU资源。

再次,GPU上运行的代码,是由主机代码调用。

例子分析

举个简单的例子,来源于书中示例。

__device__ int addem( int a, int b ) {
    return a + b;
}

__global__ void add( int a, int b, int *c ) {
    *c = addem( a, b );
}

int main( void ) {
    int c;
    int *dev_c;
    HANDLE_ERROR( cudaMalloc( (void**)&dev_c, sizeof(int) ) );

    add<<<1,1>>>( 2, 7, dev_c );

    HANDLE_ERROR( cudaMemcpy( &c, dev_c, sizeof(int),
                              cudaMemcpyDeviceToHost ) );
    printf( "2 + 7 = %d\n", c );
    HANDLE_ERROR( cudaFree( dev_c ) );

    return 0;
}

从__global__和__device__修饰符,可知 add 和 addem 将会运行在GPU,实现两个数值的求和。除了函数前的修饰符,跟标准的C函数没有任何差别。

程序运行在主机CPU,运算部分放在GPU。肯定有一个幕后黑手,将数据和运算代码搬到GPU里去。幕后黑手提供了cudaMalloc让我们GPU端分配内存。上面的例子分配了sizeof(int)大小的GPU内存给dev_c。调用add的方式:add<<<1,1>>>(2,7, dev_c);跟普通函数调用有所不同,前面添加了<<< >>>。这种方式提示幕后黑手,在主机代码中加上一部分代码,将add指令和参数传输到GPU里,并让其执行。

cudaMemcpy的作用是在主机内存和GPU内存之间拷贝数据。显然跟普通memcpy不一样的,它或许需要经过PCIe接口,来传输数据。例子中,cudaMemcpy把dev_c里的内容传输给主机变量c。

cudaFree 用于释放掉GPU内存,它跟cudaMalloc成对使用,不能跟主机上分配和释放内存的malloc和free混用。

附言

cuda by exmaple的代码我已经从github下载下来,上传到csdn。方便访问不了github的同学使用。

cuda by example 例子


原文地址:https://blog.csdn.net/dairyman000/article/details/142785409

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!