CUDA C++ Best Practices Guide读书笔记

性能优化,量化意识为王。

阅读大纲

目标:系统掌握 CUDA 优化知识,服务于 tiled 矩阵乘 + FlashAttention 实现

策略:读一层、做一层,交替进行,不要先读完再动手


Layer 1:GPU 执行心智模型 ✅

章节:Ch3 --- Heterogeneous Computing

核心问题

  • GPU 为什么需要数万个线程?
  • 什么代码适合放 GPU?
  • 延迟隐藏(Latency Hiding)是什么,依赖什么条件?

Layer 2:学会用数字衡量性能

章节:Ch9 --- Performance Metrics

核心问题

  • 如何计算 Theoretical Bandwidth(理论带宽上限)?
  • 如何计算 Effective Bandwidth(kernel 实际使用的带宽)?
  • 两者之比说明了什么?

动手:对 naive 矩阵乘 kernel 测量实际带宽,和理论上限对比


Layer 3:内存优化(最重要)

章节:Ch10 --- Memory Optimizations

阅读顺序

复制代码
Host ↔ Device 数据传输(PCIe 瓶颈)
    ↓
Global Memory Coalescing(合并访问)  ← 重点
    ↓
Shared Memory + Tiling               ← 重点,FlashAttention 核心
    ↓
L1/L2 Cache、Texture Memory          ← 了解即可

动手

  • 实现 naive 矩阵乘,观察 global memory 访问模式
  • 实现 tiled 矩阵乘,对比带宽和性能
  • 用 Ch9 的方法量化优化效果

Layer 4:线程执行模型

章节:Ch6-8(Execution Configuration)+ Ch13 --- Control Flow

核心问题

  • Warp 是什么?为什么是 32 个线程?
  • Branch Divergence 如何导致性能损失?
  • Occupancy 是什么,如何影响延迟隐藏?
  • 如何配置 block/grid 大小让 SM 充分利用?

动手:为 softmax 实现做准备,理解 warp 内 reduction 的写法


Layer 5:指令级优化(按需)

章节:Ch12 --- Instruction Optimization

内容

  • 浮点精度与性能权衡
  • 快速数学函数(__float2int-use_fast_math
  • 编译器 flag

有具体性能瓶颈时再读,不需要提前啃。


暂时跳过

章节 原因
Ch4 Application Profiling 有具体项目再看
Ch16 多 GPU 先打好单 GPU 基础
Ch17-19 数字精度 按需查阅
Ch20 编译器选项 参考手册,用到再看

与 FlashAttention 实现的对应关系

FlashAttention 组件 依赖的 CUDA 知识 对应章节
Tiling(分块计算) Shared Memory 使用 Ch10
高效矩阵乘 Coalescing + Tiling Ch10
Online Softmax Warp Reduction Ch13
避免 HBM 读写 内存层次理解 Ch9 + Ch10
线程配置 Occupancy 调优 Ch6-8

Layer 1: GPU 执行心智模型(Ch3)

核心结论

CPU 设计目标:最小化延迟 (少数线程,跑得快)

GPU 设计目标:最大化吞吐量(海量线程,用并发掩盖延迟)


关键机制:Latency Hiding(延迟隐藏)

GPU 有成千上万的线程,分成若干 warp(每个 warp 32 个线程)。

当某个 warp 等待内存数据时(内存延迟约 400-800 个时钟周期),GPU 立刻切换到其他就绪的活跃 warp 继续执行,等数据回来再切回来。

为什么切换没有代价?

每个线程有独立分配的寄存器,切换时不需要保存/恢复任何状态,直接换。

延迟隐藏失效的条件:

活跃 warp 数量不足------当所有 warp 都在等内存时,没有就绪的 warp 可以切换,GPU 空转。


运算/传输比(Operation-to-Transfer Ratio)

判断一个计算是否值得放在 GPU 上,核心指标是:

ratio=运算次数传输元素数\text{ratio} = \frac{\text{运算次数}}{\text{传输元素数}}ratio=传输元素数运算次数

比值越高,GPU 越划算(传输代价被大量计算摊薄)。

矩阵加法(N×N)

项目 数量
运算次数 N²(每个元素一次加法)
传输元素数 3N²(A、B、C 各一个矩阵)
比值 O(1)

结论:不值得放 GPU。 传输代价无法被计算收益覆盖。

矩阵乘法(N×N)

项目 数量
运算次数 N³(N² 个输出元素,每个需要 N 次 multiply-add)
传输元素数 3N²(A、B、C 各一个矩阵)
比值 O(N)

结论:值得放 GPU,且 N 越大收益越高。


什么代码适合放 GPU?

  1. 运算/传输比高:大量计算,少量数据搬运
  2. 可大量并行:数万个线程同时做独立计算
  3. 数据尽量留在 GPU 上:哪怕某一步在 CPU 更快,只要能避免一次 Host-Device 传输,在 GPU 上算也值得
  4. 相邻线程访问相邻内存:为 coalescing 做准备(详见 Ch10)

与 FlashAttention 的联系

FlashAttention 的核心问题就是第一层的直接应用:

  • N×N attention 矩阵(N=1024 时约 4MB)远超 shared memory 容量(48-96KB)
  • 标准 softmax 需要看完整一行才能归一化 → 必须把完整矩阵写回 HBM(global memory)
  • Online softmax 允许分块计算(数学上消除全局依赖)+ Tiling(物理上适配 shared memory)
  • 两者结合,才能把中间结果留在 shared memory,避免反复读写 HBM
相关推荐
老鱼说AI13 小时前
CUDA架构与高性能程序设计:异构数据并行计算
开发语言·c++·人工智能·算法·架构·cuda
superior tigre4 天前
权威指南 第四章
c++·cuda·ai infra
ouliten6 天前
[CUTLASS笔记2]host端工具类
c++·笔记·cuda·cutlass
70asunflower7 天前
CUDA编程指南基础知识点总结(5)
c++·人工智能·cuda
70asunflower8 天前
CUDA基础知识巩固检验练习题【附有参考答案】(5)
人工智能·cuda·cpp
70asunflower8 天前
CUDA基础知识巩固检验练习题【附有参考答案】(6)
c++·人工智能·cuda
封奚泽优21 天前
使用mmdetection项目进行训练记录
pytorch·python·cuda·mmdetection·mmcv
fpcc22 天前
并行编程实战——CUDA编程的其它Warp函数
c++·cuda
Autumn729923 天前
【系统重装】PYTHON 入门——速通版
开发语言·python·conda·cuda