在过去的 20 天里,我踏上了一段令人难以置信的学习之旅,以掌握 CUDA 编程,这是一个强大的并行编程框架,主要用于 GPU 加速。下面,我记录了我在这段经历中的进展、亮点和关键见解。
第一天:向量加法
我通过使用简单的 CUDA 程序实现矢量加法开始了我的旅程。这涉及:
- 编写我的第一个 CUDA 内核。
- 了解网格、块和线程层次结构。
- 使用
cudaMalloc
、cudaMemcpy
和cudaFree
分配和管理设备内存。
阅读: PMPP 书的第一章介绍了并行编程、CUDA 架构和 GPU 执行模型。
第 2 天:矩阵加法
通过设计二维矩阵的网格和块布局,我将我的知识扩展到矩阵加法。学习要点包括:
- 二维网格中的线程索引。
- 同步线程以防止竞争条件的技术。
阅读: PMPP 书中关于 GPU 可扩展性和大规模并行性的第 2 章。
第三天:矩阵向量乘法
我实现了矩阵向量乘法,其中每个线程计算矩阵行和向量之间的点积,从而导致:
- 通过使用共享内存提高效率。
阅读:第 3 章的一半,重点是可扩展的并行执行。
第 4 天:并行减少
在计算部分和的过程中,我了解了基于树的归约算法,并强调:
- 最大限度地减少扭曲发散。
阅读:完成第 3 章,探索资源分配和延迟容忍度。
第 5 天:层标准化
我解决了实现层标准化(深度学习中的关键操作)的问题,并重点关注:
- 并行计算均值和方差。
阅读:第 4 章,深入研究内存优化和性能调优。
第 6 天:矩阵转置
在此阶段,我通过利用共享内存来减少全局内存访问来优化矩阵转置。
阅读:第 5 章,我了解了性能注意事项和高级共享内存的使用。
第 7 天:一维卷积
我实现了简单版本和平铺版本的一维卷积:
- 通过优化内存访问模式,我减少了全局内存延迟。
阅读:第 7 章关于卷积技术。
第 8 天:前缀和
我实现了用于并行前缀和计算的 Brent-Kung 算法,了解了:
- 分层扫描算法和线程同步。
阅读:第 8 章重点介绍前缀和的并行模式。
第 9-10 天:快速关注
我为 Flash Attention 开发了前向传递,但面临着数值稳定性的挑战。我还在第 10 天进一步优化了它。
我还发表了一篇关于它的热门帖子!
阅读:探索了 Flash Attention 论文,加深了我对注意力机制的理解。
第 11 天:稀疏矩阵向量乘法
我创建了一个优化的稀疏矩阵向量乘法算法,并编写了一个基准测试脚本来与 PyTorch 进行性能比较。
阅读:关于稀疏矩阵计算的第 10 章。
第 12 天:合并排序
我使用并行方法实现了合并排序算法,深入了解如何有效地合并两个已排序的数组。
阅读:第 11 章,重点介绍合并排序并行化策略。
第 13 天:BFS 和 GELU 激活
我探索了高级算法,实现了广度优先搜索优化内核和 GELU 激活函数,这在神经网络中至关重要。
阅读:第12章和第13章,增强了我对图算法和动态并行性的理解。
第 14 天:MRI 重建
我致力于非笛卡尔 MRI 重建的 FHD 算法,将理论知识与医学成像的实际应用相结合。
阅读:第 14 章,研究迭代重建技术。
第 15 天:Flash 注意力反向传播
我实现了 Flash Attention 的反向传播步骤,处理梯度计算并优化内存使用。
阅读:第 15-17 章有关分子可视化和机器学习的应用案例研究。
第 16 天:朴素贝叶斯分类器
我创建了一个 CUDA 加速的朴素贝叶斯分类器,优化训练过程以有效处理特征概率。
阅读:更新了我的博客,介绍了在 Colab 中使用 NVCC 的见解。这个博客也掀起了一股潮流!
第 17 天:使用 cuBLAS 进行矢量加法
我学习了 cuBLAS 库的基础知识,并使用cublasSaxpy
实现了向量加法,通过优化的例程增强了性能。
第 18 天:使用 cuBLAS 进行矩阵乘法
继续使用 cuBLAS,我实现了矩阵乘法,加深了我对高性能线性代数运算的理解。
第 19 天:全连接神经网络
我使用 cuDNN 构建了一个全连接神经网络,探索张量描述符、滤波器描述符以及 GPU 上神经网络的复杂性。
第 20 天:旋转位置编码
我通过在 CUDA 中实现旋转位置编码 (RoPE) 机制来结束这次学习冒险,增强了用于顺序数据处理的变压器模型。
结论
这 20 天的 CUDA 学习是变革性的。我平衡了 PMPP 书籍提供的理论基础与实践编码项目,加深了我对并行编程和 GPU 架构的理解。随着我的前进,我计划继续完善实现并探索 CUDA 编程中更高级的主题。
请继续关注我的旅程的进一步更新!
原文: https://hamdi.bearblog.dev/my-20-day-journey-learning-cuda-from-scratch/