CUDA多GPU编程入门
多gpu有几种模式,多线程+cuda,也有通过流并发+cuda
stream和异步拷贝
左边的在时间上顺序执行,使用stream可以实现右边的操作——同时做4步操作
note:AB如果都需要做kernel的加载,并且需要使用GPU的内存,
对于左图来说:AB可以占用到最大的GPU内存(占满)
对于右图来说,则两者的总的内存不能超过gpu的总内存
stream使用的步骤:定义流,创建流,销毁流
1:定义了两个流,s1,s2
2:用函数cudaMemcpyAsync函数异步传输
1,2,用的时间一样,1s
3:创建两个流,同时运行AB,AB 在不同的流上同时运行,异步流形式是共用的时间,也是1s
为啥要使用流呢
左边占满gpu的内存,gpu计算完了以后再传回主机,然后再把下一块内存传到GPU上
如果使用流就是右边的图:第一次复制半个大小的GPU内存上去运行,同时拷贝第二个半个大小的GPU内存到GPU上去,这样就是拷贝不影响数据处理的操作
从时间上看,拷贝数据和另外一边的数据处理是有重叠的,而且线程块分的更小,把每一个kernel函数填满了容易
两个点:1,什么时候用什么方式选择哪个GPU去运算
2,不同GPU之间的通信,GPU与CPU的通信
首先,要知道什么时候用什么方式选择哪个GPU去运算,就要先确定GPU的状态是否可用
P2P可以进行跨GPU的复制,对跨GPU地址引用,
使用CUDADeviceEnablePeerAccess允许当前的GPU访问目标GPU——peer_device GPU
先用这个函数设置允许访问,不可访问是没有办法读取到里面的东西的,所以要检查当前设备和目标设备是否可以访问,返回1可以访问,返回0不可以访问,返回值在函数第一个参数里。
setdevice设置当前用的GPU
可以访问就设置当前可以使用GPU2
要启动GPU2对GPU1的访问
上面这个函数做两个设备的数据拷贝
纹理内存
纹理内存:只读内存,对性能,带宽,内存阻塞,最早期用来处理图形处理
纹理内存,存在于每一个SM上,是局部空间的一个形式,
对内存读取——texture fetch
纹理内存可以被指定为1D,2D,3D的内存数组与cudaArrays关联,进行绑定以及使用
cudaArrays是专门为了纹理内存而设计的,由设备上的内存进行分配,直接是GPU上边的一个数组模式,但是不消耗CUDA的地址空间
特点:全局内存,可以缓存,可以直接读取内容到线程里使用
读取纹理内存中的数据,
首先要先绑定一个CUDA数组,首先定义纹理内存,和一个cuda数组绑定在一起,然后再从数组中读取到里面的内容,解除绑定,具体步骤如下
模板方式定义如下:
将testure_reference,和cuda数组或者设备指针(devptr)绑定在一起
根据纹理内存是1D,2D,3D来写这个读取的函数
CPU/GPU协同
红色数据部分—移动可以复制的区域(staging)再—复制到GPU
利用cudaHostMalloc,可以直接从staging状态开始,
cudaHostRegister规定复制哪一块的数据,直接复制到GPU
CPU和GPU是两个芯片,通过PCIe进行比较高速的传输
以上是看的B站上的课做的笔记
https://www.bilibili.com/video/BV1if4y1i7yp/?spm_id_from=333.880.my_history.page.click