为什么要学习GPU或CUDA C编程
AI、科学计算等应用场景中需要对模型、算法进行加速,自定义cuda c算子可以让算法跑的更快,针对算法利用硬件特性进行优化。
例如ai中目前常用的pytorch框架,运行模型时,gpu版本后端中调用的其实就是CUDA C编写的算子(或者说函数),因此当我们配置环境时,配置CUDA和cuDNN等都是为了使用这些后端的支持,从而让我们用python写的模型算法最终能够跑在GPU上,高速运行。
当然,要写出能够在GPU上高速运行的程序不一定完全依赖于CUDA C编程框架,只是CUDA近些年来都非常主流和垄断,当前OpenAI的Triton有一种取代CUDA C的野心,试图降低用户的GPU编程门槛。
学习GPU编程的难点
如何写出一个高性能(跑得快)的GPU程序:
- 需要发掘上层算法中的并行性
- 对目标硬件结构有充分的了解
- 结合两者的计算和访存特点,将算法映射到目标硬件上
学习路线
入门
1、理解cuda c和gpu结构
官网的编程指南:
中文(翻译)版:
2、学习gpu结构
一篇梳理了NV GPU各代架构的发展和迭代过程的优秀文章:
zhuanlan.zhihu.com/p/394352476
3、写代码
参考书:《CUDA by Example》 中文译本:《GPU高性能编程CUDA实战》
4、其他
对于各种概念讲的较为深入的一本书:《Professional CUDA C Programming》中文译本:《CUDA C编程权威指南》
参考博客:人工智能编程|谭升的博客
这个阶段,你应该对以下两张图都有了一定的理解:
进阶
这个阶段需要你不断的编写代码,进行性能测试和瓶颈分析,并加深对硬件特性的理解。
1、学习优秀的kernel代码
推荐可以多看别人写的kernel代码,并自己尝试写一些涉及reduce、共享内存操作的代码,这里推荐一个github,里面写了一些AI中常用的算子:
写AI算子的话,推荐 激活函数(element-wise)算子 -> softmax/normalization算子 -> 矩阵乘gemm(conv)这样逐步增加难度去学习;即按照 简单加减乘除运算 -> reduce运算 -> 矩阵乘运算 这样逐步增加难度,并且可优化空间也会变得更大。
2、学习使用性能分析工具
强烈推荐学习使用性能分析工具,如nvidia提供的nsight compute,或者硬件公司自己开发的工具等,查看kernel内部各种计算、访存的耗时情况,指令发射情况等等,这个阶段也可以开始看汇编代码了,可以使用compiler explorer查看生成的汇编代码,分析指令生成和排布情况等,帮助我们进一步理解硬件行为。
3、加深对硬件的理解
加深对硬件的理解,至少要理解GPU中的一些访存合并、bank conflict之类的一些原理,并在代码中运用这些硬件特性,这里推荐一本gpgpu的架构书:
《通用图形处理器设计:GPGPU编程模型与架构原理》
然后就是看nvidia每一代架构的whitepaper,会有nv官方的对每代硬件的介绍。
PS:参考文章