CUDA多线程编程

一、头文件

1、cuda_runtime.h

CUDA 目前有两种不同的 API:Runtime API 和 Driver API,两种 API 各有其适用的范围。由于 runtime API 较容易使用,一开始我们会以 runetime API 为主。
cuda_runtime.h头文件一般就是Runtime API中,运行时的API和其参数的定义。(如果使用Driver API,驱动API则头文件使用cuda.h)。

2、device_launch_parameters.h

要使用threadIdx、blockIdx、blockDim等内置变量时要在头文件里导入device_launch_parameters.h

二、对设备函数的一些操作

1、thrust容器

(1)声明与使用
Trust 提供了两个vector容器:host_vector 与 device_vector。按照命名规则,host_vector位于主机端,device_vector位于GPU设备端。Trust的vector容器与STL中的容器类似,是通用的容器,可以存储任何数据类型,可以动态调整大小。
代码示例:

thrust::device_vector<float>& ZXY

其中,thrust::告诉编译器在thrust命名空间中查找函数与类;device_vector表示使用的容器位于GPU设备端;定义的容器类型是float;容器中存放的是ZXY的地址。
应用实例:

thrust::device_vector<float> d_xds(xds, xds + DNU);

初始化一段内存,d_xds表示初始化的容器名称,其中的xds表示起始指针,xds + DNU表示结束指针。
(2)清除
clear()
代码示例:

thrust::device_vector<float> vol(hvol, hvol + siz);
vol.clear();

其中vol为一个容器,第二行代码clear()表示清楚其中数据,但容器整体结构并未改变。

三、CUDA流

介绍:
1、流可以看成是在设备上work的一个队列,host端将work加入队列,然后继续添加。设备在资源free时,开始调度streams里面的work。
2、CUDA的操作也是在流里面,比如Kernel的启动,内存的拷贝。
3、在同一个流里面的操作是有序的(FIFO),不可以重叠了。
4、在不同的流里面的操作是无序的,可以重叠。
用法:

cudaStream_t stream; //声明一个stream
cudaStreamCreate(&stream); //分配stream
cudaStreamDestroy(stream); //取消分配的stream,在stream中的work完成后同步host端。

除非是特别指定了stream,所有的调用都放在默认流里。这个默认流通常指的是“Stream 0”。
参考网页

四、核函数

官方的文档称为函数执行环境标识符Function execution space specifiers,也就是他指明了这段函数是在哪里被调用的。

__global__

这个前缀修饰的函数是核函数,这些函数在CPU端调用,在GPU上执行。
注意:
(1)修饰的函数必须采用void返回值,并且需要在调用时制定运行的参数 (也就是<<<>>>里的block数和thread);
(2)任何对__global__函数的调用都必须指定该调用的执行配置。执行配置定义将用于在该设备上执行函数的网格和块的维度,以及相关的流。
(3)函数是异步的,这也代表着函数没被执行完就返回了控制权,所以测量核函数的时间需要同步操作才能获得准确的结果。
代码示例:

 naive_copyToTwoVolumes << <gid, blk >> >(函数的输入参数)

其中,尖括号作用为线程配置,gid类型若为dim3,指定网格的维度和大小,gid.x * gid.y * gid.z 等于所启动的块数量;blk的类型若为 dim3,指定各块的维度和大小,Db.x * Db.y * Db.z 等于各块的线程数量;这些参数并不是传递给设备代码的参数,而是告诉运行时如何启动设备代码。传递给设备代码本身的参数是放在圆括号中传递的。

五、cuda kernal中的block、grid、thread

threadIdx、blockIdx、blockDim和gridDim

threadIdx  //uint3类型,表示一个线程的索引。
blockIdx  //uint3类型,表示一个线程块的索引,一个线程块中通常有多个线程。
blockDim  //dim3类型,表示线程块的大小。
gridDim  //dim3类型,表示网格的大小,一个网格中通常有多个线程块。

以上涉及到线程、线程块、线程格的知识,下面是它们之间关系的示意图。grid表示线程格,一个线程格内包含许多block线程块,而一个线程块内又包含许多线程thread,其中线程块和线程都可以是一维、二维或三维的。
在这里插入图片描述
若线程格和线程块都是三维矩阵。这里假设线程格是一个3×4×5的三维矩阵, 线程块是一个4×5×6的三维矩阵,则有:
(1)gridDim
gridDim.x、gridDim.y、gridDim.z分别表示线程格各个维度的大小:

gridDim.x=3
gridDim.y=4
gridDim.z=5

(2)blockDim
blockDim.x、blockDim.y、blockDim.z分别表示线程块中各个维度的大小:

blockDim.x=4
blockDim
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值