GPU与并行计算
【参考:[CUDA编程(二):基本项目建立流程](https://blog.csdn.net/xierhacker/article/details/52473747)
[GPU编程 | 并行计算的helloworld!](https://blog.csdn.net/qiu931110/article/details/88753630)
[GPU并行计算与CUDA编程](https://blog.csdn.net/milk_and_bread/article/details/108765975)】
【说明:本文的图基本引用上述博文,但他们的文章的写作逻辑和表述方式都有不同程度的欠缺,在借鉴学习后,用自己的方式,尽可能站在读者角度去分析,更多可能作为个人笔记,如果对大家有帮助,当然也很开心,如果本文有不当之处或不明白的地方,请在评论区批评指正,欢迎交流探讨,再次感谢大家的阅读】
GPU进行并行计算的原理
GPU在进行并行计算时,是以核(kernel)为单位进行的
每个核由若干线程块(thread block)负责运算,而每个线程块又由若干个线程组成(核可看作一个功能函数)
GPU包含若干个流处理器(SM),越多GPU性能越好
SM:simple processor:处理单元 memory:存储单元
SM结构图如下:
GPU中每个流处理器(SM)独立并行工作,用以计算CPU发送过来的核(内核是操作系统的核心程序,在运行时需要加载到计算机存储器中运行):
编程原则:
- 所有在同一个线程块上的线程在同一时间必然运行在同一个SM上(一个内核很多线程块,每个线程块会在同一时间按一定策略分配给各个SM处理,这是并行)
- 同一个内核的所有线程块必然全部完成之后,才会运行下一个内核(不同线程块在不同SM上运行时间不同,但这些线程块属于同一个内核,所以必须整个内核中涉及到的运算全部完成,才能执行下一个有先后逻辑关系的内核,这是串行)
GPU中SM说明:
- 一个SM中有多个处理单元,所以可以运行多个线程块
- GPU中有若干个SM,大家看到这篇时可以查下目前最多可达多少个
- 每个SM并行(共同处理一个项目)而独立运行(各个部门干好自己的事)
GPU中M说明:
不同内存间的访问速度如下图所示,因此要想加快计算速度,我们的核心思想就是将整体计算切分,使得每次的计算规模越小,计算次数越多,那么程序的速度也就越快。这是从内存访问的角度说明了GPU并行计算的优势:
CUDA操作GPU的流程
- CPU分配空间给GPU(cudaMalloc():在设备(GPU)上面分配内存,而不是在主机(host)上面)
【主机(host):CPU及系统的内存 设备(device):GPU及其内存】
原型:__host____device__cudaError_t cudaMalloc(void**devPtr, size_t size)
参数:
devPtr:主机一个指针变量的地址,到时候某个设备内存的地址就存放在这里
Size:需要分配的空间的大小
返回值:
cudaSuccess, cudaErrorMemoryAllocation
描述:Allocates size bytes of linear memory on the device and returns in *devPtr a pointer to the allocated memory. The allocated memory is suitably aligned for any kind of variable. The memory is not cleared. cudaMalloc() returns cudaErrorMemoryAllocation in case of failure.
The device version of cudaFree cannot be used with a *devPtr allocated using the host API, and vice versa.
- CPU复制数据给GPU(cudaMemcpy():访问设备内存的必备函数)
原型:__host__cudaError_t cudaMemcpy (void *dst, const void *src, size_t count, cudaMemcpyKind kind)
参数:
dst:被拷贝的内存地址(就是拷贝的东西会放到这里来)
src:拷贝的源地址(就是从这里拷贝)
count:拷贝的数量(单位是字节bytes哦)
kind:拷贝的方式,有下面几种
cudaMemcpyHostToHost
cudaMemcpyHostToDevice
cudaMemcpyDeviceToHost
cudaMemcpyDeviceToDevice
返回值:
cudaSuccess, cudaErrorInvalidValue, cudaErrorInvalidDevicePointer,
cudaErrorInvalidMemcpyDirection
- CPU加载kernels给GPU作计算
- CPU把GPU的运算结果复制回来