CUDA Kernel
3 秒看懂
CUDA Kernel 是运行在 NVIDIA GPU 上的一段并行程序,一次启动会生成成千上万个轻量线程,同时处理数据的不同部分。在深度学习中,几乎所有算子的实际执行(矩阵乘法、卷积、注意力计算等)最终都被编译或映射为最优的 CUDA Kernel,它就是 AI 算力底层的“原子作业”。
3 分钟产业解释
可以把 CUDA Kernel 想象成在工厂流水线上同时工作的数万名工人:每个工人只处理极微小的一件任务,但合起来能瞬间加工完一整批货物。CPU 像是少数几个精密的工程师,擅长复杂的逻辑控制和低延迟任务;GPU 则靠 CUDA Kernel 调度成百上千个“简单工人线程”,以极高吞吐量吞噬大规模并行计算。
在 AI 产业里,数据科学家用 PyTorch、TensorFlow 写一行 torch.matmul 或 F.conv2d,框架底层就会调用 NVIDIA 的 cuBLAS、cuDNN 等库,这些库里封装了手写调优到极致的 CUDA Kernel——它们针对 Tensor Core、共享内存、数据预取等做了大量微架构级别的优化。可以说,控制了 CUDA Kernel 的效率和生态,就等于控制了 AI 训练与推理的实时成本和性能天花板。这也是为什么其他 AI 芯片公司不得不投入大量资源构建自己的编译器和算子库,以突破 CUDA 的“软硬件一体”护城河。
15 分钟专家深入
CUDA Kernel 代码使用带扩展的 C++ 编写,通过 nvcc 编译为 GPU 可执行的机器码。启动一个 Kernel 时,程序员需要指定线程层次:
- 整个任务空间叫一个 grid,可以是一维、二维或三维,适应图像、矩阵或张量的形状。
- 每个 grid 被分解为许多 block,每个 block 包含最多 1024 个线程(这是编程模型的限制,实际可调度量由硬件资源决定)。
- 每个 block 内的线程又分组为 warp(固定 32 个线程),warp 是 GPU 执行和调度的最小单元。
内存层次是性能的关键:同一 block 内线程共享极快的 shared memory,block 之间可通过 global memory(显存)交换数据,另外有只读的 constant memory、texture memory 和每个线程专有的 local memory(位于显存中的私有存储区,当寄存器溢出时被使用)。CUDA Kernel 的优化大量围绕“如何把数据从缓慢的 global memory 搬运到 shared memory,做足计算再写回”展开。
深度学习中的典型 Kernel 包括:
- 矩阵乘法 (GEMM):采用 tiling 策略,将大矩阵切成小片,每片由 block 计算,子片由 warp 和 thread 协作完成,中间结果暂存在 shared memory 和寄存器中,最大化数据复用。
- 卷积:早期使用 im2col 将卷积转换为矩阵乘法;现代实现多采用 Winograd 算法或直接利用张量核心的 Implicit GEMM。
- 注意力机制 (Softmax + MatMul):像 FlashAttention 这样的 Kernel,重排了计算顺序,以分块方式加载 Q、K、V,在线计算 softmax 并累计结果,避免将整个注意力矩阵写入慢速显存,极大降低 IO,是近年来 LLM 推理加速的里程碑。
- 融合算子:将多个连续操作(如 layer norm + gelu)合并成一个 Kernel,消除中间数据的显存往返,是编译器优化(如 XLA、Triton)的核心能力。
此外,Tensor Core 是一种专门加速矩阵乘积累加(MMA)操作的硬件单元,通过特殊的内联指令(如 mma.sync)可在 Kernel 中调度,提供远超通用核心的矩阵运算吞吐,但需要精心对齐数据和形状。
技术原理(最深)
线程组织与调度
CUDA Kernel 的启动配置记为 <<<gridDim, blockDim, sharedMemBytes, stream。每个线程内置三维索引变量 threadIdx(block 内位置)、blockIdx(grid 内位置)、blockDim 等,用于计算全局数据索引。
grid 由 2×2 个 block 组成
-------------------------
| Block (0,0) | Block (0,1) |
| thread 0 | thread 0 |
| thread 1 | thread 1 |
| ... | ... |
-------------------------
| Block (1,0) | Block (1,1) |
-------------------------
每个 block 被分配到某个 Streaming Multiprocessor(SM)上执行。SM 内包含多个 warp scheduler,每个周期选择一个就绪 warp 下发指令。warp 内所有线程执行同一条指令(SIMT 模型),若发生分支(if-else),不同路径会被依次串行执行(warp divergence),导致效率损失。
内存模型与延迟隐藏
GPU 没有 CPU 那样复杂的缓存预测和乱序执行,而是靠大量并发线程来隐藏内存延迟。当 warp 因 global memory 访问而暂停时,warp scheduler 立刻切换到另一个已就绪的 warp。所以保持 SM 上有足够多 active warps(高占用率)是隐藏延迟的关键,但占用率并非绝对越高越好——如果寄存器或 shared memory 消耗过大,反而会限制并行 warp 数量。
Shared memory 是片上 SRAM,bank 数目和位宽因架构而异。如果同一个 warp 内多个线程同时访问 shared memory 的同一个 bank 的不同地址,会发生 bank conflict,降低有效带宽。优化 Kernel 时会精心设计数据布局和访问步长来避免。
深度学习典型 Kernel 微观机制
以分块矩阵乘法 C[M,N] += A[M,K] * B[K,N] 为例(简化 tile 算法):
for (int i = 0; i < M; i += BM)
for (int j = 0; j < N; j += BN) {
// 将 A 和 B 的子块载入 shared memory
for (int k = 0; k < K; k += BK) {
// 各线程协作加载 A[i:i+BM, k:k+BK] 到 sh_A
// 各线程协作加载 B[k:k+BK, j:j+BN] 到 sh_B
__syncthreads();
// 每一个线程计算部分乘积并累加局部寄存器
for (int ki = 0; ki < BK; ki++)
C_reg += sh_A[ty][ki] * sh_B[ki][tx];
__syncthreads();
}
// 将寄存器结果写回 global memory
C[全局行][全局列] = C_reg;
}
其中 __syncthreads() 是 block 内 barrier,确保所有线程都完成了 shared memory 写入后,再开始下一步计算。无此同步则数据竞争。
在利用 Tensor Core 的 Kernel 中,上述局部 inner product 会被替换为一条 MMA 指令,一次性计算一个 16×16 或更大小块的矩阵积并累加,配合 shared memory 的奇异排列避免 bank conflict,这类 Kernel 的汇编级调优接近硬件极限。
关键参数(定性,随架构变化)
- Warp size:固定为 32 线程。
- 每个 SM 的最大 resident warps / threads:取决于寄存器文件和 shared memory 容量,不同 GPU 差异极大。
- Shared memory 大小:架构决定,部分 GPU 可配置 shared memory 和 L1 缓存之间的划分比例。
- Tensor Core 支持的 MMA 尺寸:16×16×16、8×32×16 等,不同精度 (FP16, BF16, TF32, INT8) 形状不同。
- 内存带宽、峰值 TFLOPS:完全由具体 GPU 型号决定,不做死板陈述。
技术演进史
- 2006 年:NVIDIA 发布 CUDA 1.0,首次将 GPU 抽象为通用并行计算设备,引入 Kernel 编程模型和 nvcc 编译器。早期的 Kernel 多用于科学计算,深度学习尚未兴起。
- 2012 年前后:AlexNet 使用 CUDA 实现卷积,标志着深度学习开始融入 CUDA 生态,但此时 Kernel 多由研究者手写,效率参差。
- 2014 年:cuDNN 推出,提供高度优化的卷积、池化等深度学习基本 Kernel,让框架可直接调用,大幅降低优化门槛。
- 2017 年 Volta 架构:引入第一代 Tensor Core,彻底改变深度学习算子形态。Kernel 中不再只用 CUDA Core 做标量乘加,而是通过
wmmaAPI 或内联 PTX 利用硬件矩阵引擎,通用矩阵乘法性能提升数倍。 - 2018–2020 年 Turing、Ampere:扩展 Tensor Core 精度(TF32、BF16、INT8、INT4),引入稀疏矩阵支持,Kernel 设计需要考虑选择正确的 MMA 指令和输入数据类型。
- 2022 年 Hopper 架构:新增 Tensor Memory Accelerator (TMA) 和基于描述符的异步拷贝,允许 Kernel 通过描述符异步在 shared memory 和 global memory 间搬运数据,从而将复杂的内存调度从计算逻辑中分离,极大简化了 flash attention 之类 IO 密集型 Kernel 的实现。同时在软件层面,Triton 语言兴起,使得编写高效 GPU Kernel 的门槛降低,其生成的 CUDA Kernel 在部分场景已接近手写优化效果。
- 未来趋势:多 Kernel 协同(CUDA Graphs)、动态并行、自动调优系统(如 TVM、Triton)将持续演化,CUDA Kernel 可能越来越多由编译器合成,而非人手编写。
技术路线对比(量化表)
| 特性 | CUDA Kernel | OpenCL Kernel | HIP Kernel (AMD) | Intel OneAPI (SYCL) | Apple Metal Shader |
|---|---|---|---|---|---|
| 平台 | NVIDIA GPU 专属 | 跨平台 (GPU/CPU/FPGA) | AMD GPU 原生,可跨平台 | Intel GPU/CPU/FPGA | Apple GPU / Intel/AMD on Mac |
| 原生编程语言 | C++ 扩展,PTX 内联 | C99 扩展 | C++ 扩展(与 CUDA 高度相似) | 标准 C++ 与 SYCL 队列 | Metal Shading Language (C++14) |
| Tensor Core / 矩阵加速 | 一级支持,有专用内联指令 | 无标准专用加速,需靠厂商扩展 | 有类 Tensor Core,但 API 不同 | Intel XMX 矩阵引擎支持 | Apple Neural Engine 通过 MPS 暴露,非直接 Shader 访问 |
| 生态成熟度 | 极深,cuDNN/cuBLAS/TensorRT/PyTorch 原生支持 | 生态较弱,缺乏专用 DNN 库 | ROCm/MIOpen 逐步追赶,兼容层翻译 CUDA | 新兴,oneDNN 部分支持 | Core ML / MPSGraph 掩盖底层,Shader 不直接用于主流训练 |
| 典型深度学习框架支持 | PyTorch, TensorFlow, JAX 一级优化 | 几乎无直接使用 | PyTorch 已支持 ROCm | 早期支持,PyTorch 有实验性后端 | PyTorch MPS 后端为 Metal 封装,不上手写 Shader |
| 性能天花板 | 最高,厂商调优至极限 | 受限于平台和驱动成熟度 | 接近 CUDA,部分场景持平或略低 | 发展期,潜力待验证 | 适合推理,大规模训练尚不成熟 |
上下游
- 上游:CUDA C++ 源代码、PTX 中间表示、
nvcc编译器、针对不同 GPU 架构的 SASS 指令集;算法层面的线性代数库、循环分块策略、数据布局设计。 - 中游:Kernel 本身(源码或二进制 cubin);手写与自动生成的分界线是 NVIDIA 库、编译器(如 Triton、XLA)及自动调优工具。
- 下游:
- 硬件执行单元:SM(包括 CUDA Core、Tensor Core、LD/ST 单元、SFU 等),互联结构,L1/L2 缓存,HBM 控制器。
- 运行时系统:CUDA Driver / Runtime API,管理上下文、stream、event 等,将 Kernel 下发到命令队列。
- 上层软件栈:深度学习框架(PyTorch、TensorFlow、JAX),推理优化器(TensorRT),强化学习、推荐系统、LLM 推理等服务。
- 最终应用:大语言模型训练(MOE 路由 Kernel)、实时推理(FlashDecoding)、自动驾驶感知(点云卷积 Kernel)等。
从 AI 产业链视角,CUDA Kernel 是“软件定义硬件性能”的终极体现:同样的 Transformer 架构,不同 Kernel 实现在同一硬件上的吞吐可差数倍,这直接转化为云计算成本与产品体验的差异。
关键指标
评估一个 CUDA Kernel 好坏的核心维度(全定性,无固定目标值):
- 吞吐 (Throughput):单位时间完成的计算量或样本数,受制于硬件计算能力和带宽。
- 内存带宽利用率:实际数据搬运速率与 GPU 峰值带宽的百分比。许多 Kernel 是内存受限的,尤其 element-wise 操作和 softmax 等,优化集中在向量化访问和数据合并传输。
- 占用率 (Occupancy):SM 上活跃 warp 数量与理论最大值之比,过低会无法充分隐藏延迟;过高可能因寄存器/共享内存不足而失败。
- 计算利用率:计算单元(CUDA Core / Tensor Core)实际工作周期占比,避免流水线排空。
- warp divergence:同一 warp 内分支导致串行执行的程度,在 NLP 变长序列、稀疏模型中尤需警惕。
- Bank conflict 率:shared memory 访问时的冲突比例,对延迟敏感 Kernel 很关键。
- 指令混合:MMA、FMA、LD/ST 等指令的比例是否与硬件流水线匹配。
- 启动延迟:Kernel launch 本身的开支,若大量小 Kernel 串行,启动延迟可能淹没计算时间(可用 CUDA Graph 缓解)。
深度学习框架通常不直接暴露这些指标,而是通过 NVIDIA Nsight 等性能分析工具让开发者深入优化。
供需与市场数据
CUDA Kernel 本身不构成独立市场商品,它是 NVIDIA 生态的“软实力”体现。其供需更多反映为 CUDA 生态的锁定效应:
- 开发者供给:据 NVIDIA 财报电话会定性引用,CUDA 注册开发者数百万,但无精确数量验证。[未充分披露]
- 需求面:全球 AI 训练和推理工作负载的绝大部分落在 NVIDIA GPU 上,几乎所有大规模集群都在运行经高度手写或编译优化的 CUDA Kernel。Hyperscaler 和 AI 初创公司为了极致的 TCO 会持续投入工程资源进行自研 Kernel 开发(如 Megatron-LM、vLLM 中的定制算子),形成内部“Kernel 工程师”的强力需求。
- 竞争动态:随着 PyTorch 2.0 编译栈(TorchInductor)和 OpenAI Triton 的流行,很多高性能 Kernel 开始由 Python DSL 生成,降低了对直接编写 CUDA 代码的依赖。但当前真正顶级性能的 Kernel(如 FlashAttention-3)依然离不开对 CUDA 汇编和硬件细节的深刻理解。这股 Kernel 自动化浪潮 在中期可能部分侵蚀 CUDA 手写生态,但短期仍受限于编译器成熟度和目标硬件支持范围。
代表公司与资本映射
- NVIDIA:CUDA Kernel 生态的绝对构建者与控制者。不仅提供编译器、库,还通过 GTC 大会、文档、样例、研究人员合作等营造了不可替代的开发者社区。其数据中心收入(财报口径)绝大部分由 CUDA 生态支撑。
- AMD:通过 HIP(Heterogeneous-compute Interface for Portability)实现 CUDA 到 AMD GPU 的转译和原生开发;ROCm 栈下的 MIOpen 库对标 cuDNN,但人力规模和成熟度差距明显。资本层面,AMD 数次收购(如赛灵思)以增强整体系统能力,挑战 NVIDIA 的“CUDA 护城河”是其主要叙事。
- Intel:借 oneAPI 和 SYCL 统一编程模型,同时为数据中心 GPU(Ponte Vecchio 系列)建立底层算子库;结合 Habana 加速器专有软件栈,试图从训练侧切入。
- 云厂商自研芯片:Google TPU 使用多级编译器(XLA)生成针对 Systolic Array 的 Kernel,完全不兼容 CUDA;AWS Trainium 的 Neuron SDK 编译器自动生成配合其近存计算架构的内核;这些“非 CUDA 路线”在资本市场被视为对 NVIDIA 生态的部分替代威胁。
- 初创公司与工具:OpenAI 发布 Triton 语言,能使开发者用 Python 编写接近手工 CUDA Kernel 性能的代码,降低了 GPU 编程门槛;Modular 公司的 Mojo 语言和 MAX 引擎试图取代 CUDA 的底层地位。这些项目一旦成功,可能重新定义 Kernel 的“谁来写、怎么写”。
产业链观察逻辑
- 生态护城河价值:CUDA Kernel 对 AI 训练推理的深度渗透,形成数千万行优化代码和数十万熟练开发者积累,使替换成本极高。这是 NVIDIA 数据中心业务高毛利、高粘性的根基之一。
- 软硬脱钩风险:如果主流框架(如 PyTorch)完全偏向编译器自动生成 Kernel,且后端能完美适配非 NVIDIA 硬件(如通过 OpenXLA/StableHLO),那么手写 CUDA Kernel 的优势可能被稀释,硬件竞争将更聚焦于芯片算力和能效本身。
- 细分机会:专注 Kernel 优化工具(如自动调优、性能剖析)的初创公司;具备极致 CUDA 调优能力的 AI 推理部署公司(如 Fireworks AI 基于 vLLM 的优化),它们能通过推理降本直接创造商业价值。
- 人才价值:高端 CUDA Kernel 工程师是稀缺资源,大中型 AI 团队往往会因一两位“Kernel 大神”的存在而获得显著成本或延迟优势。研究时可跟踪人才密集的 AI 研究实验室、云服务商自研芯片团队及推理部署公司。
- 技术路径关注点:Triton 社区的增长速度、AMD ROCm 在 PyTorch 中的覆盖率、Intel oneAPI 能否吸引主流框架用户,这些是衡量 CUDA Kernel 生态长期壁垒松动的先行指标。
常见误读纠偏
误读 1:“CUDA Kernel 就是一串并行循环,用 GPU 线程自动搞定。” 纠偏:简单地把一维循环映射到线程,80% 时间可能浪费在显存访问上。高性能 Kernel 必须深刻理解内存层次和数据复用:如果不使用 shared memory 暂存块、不搞寄存器分块、不注意全局内存合并访存,性能可能只有峰值带宽的十分之一甚至更低。深度学习框架能自动生成部分算子,但极致优化仍需手工设计数据流。
误读 2:“网络结构定了,跑的 Kernel 速度都一样,性能瓶颈只在硬件。” 纠偏:同一 Attention 架构,naive 实现、内存优化实现(FlashAttention)和针对特定序列长度定制的 Kernel,吞吐量可以相差数倍。对于 LLM 推理,prefill 阶段和 decode 阶段的瓶颈不同(compute bound 与 memory bound),分别需要不同拆分策略的 Kernel。所以软件层面的 Kernel 实现直接决定了硬件投入的产出比,这也是为何头部 AI 云服务竞相招聘 GPU 系统工程师。
误读 3:“Tensor Core 可以自动加速任何矩阵乘法。” 纠偏:Tensor Core 对矩阵形状、内存对齐和数据类型有严格要求。如果输入不是对应的精度(如 FP32 做标准 MMA),或者维度不是硬件要求 tile 大小的倍数,就必须在 Kernel 中进行补边、变换数据类型,否则无法使用。这导致很多看似简单的操作(如 GEMV)并不能直接躺上 Tensor Core,需要精巧的汇编级重排。
学习路径
- 入门:NVIDIA 官方《CUDA C++ Programming Guide》前 5 章,理解线程层次、内存模型、异步并发;动手完成 “vectorAdd” 到 “matrix multiply” 的几个练习 Kernel。
- 进阶:阅读《Programming Massively Parallel Processors》(Kirk & Hwu)中关于 tiling、卷积、归并优化的章节;学习 Nsight Systems / Compute 进行性能剖析;尝试用 cuBLAS 配合手写 Kernel 实现一个简单计算图。
- 深度学习专用:学习 cuDNN 文档,理解卷积算法选择;研读 FlashAttention 论文及其开源实现中的 CUDA Kernel 代码(GitHub);学习 Triton 语言,其教程易上手且产出可直接转化为 CUDA 原生思维。
- 硬核优化:掌握 PTX 和 SASS 基本阅读能力,使用 NVIDIA 的官方工具 Micro‑benchmark 理解具体 SM 的微架构参数;阅读 CUTLASS 源码,它是 NVIDIA 官方模板库,展示了最高级别的 GEMM 和卷积 Kernel 设计模式。
- 系统性理解:结合 GPU 架构白皮书(Volta、Ampere、Hopper),对照 Kernel 如何利用 TMA、异步拷贝、Tensor Core 组合,建立 end-to-end 性能分析闭环。
一句话总结
CUDA Kernel 是释放 NVIDIA GPU 全部并行算力的最小能量单元,它在深度学习世界中的地位就相当于“机械指令之于 CPU”,却是目前看不见却最难替代的软硬生态耦合点。
延伸阅读与来源
- 由于本次检索未能获取实时网页数据,以下为权威固定来源:
- NVIDIA CUDA C++ Programming Guide(最新版随工具包发布),docs.nvidia.com/cuda/
- NVIDIA GPU Architecture White Papers(Volta, Turing, Ampere, Hopper),nvidia.com
- FlashAttention 论文与 GitHub 仓库:Dao-AILab/flash-attention
- CUTLASS(CUDA Templates for Linear Algebra Subroutines):github.com/NVIDIA/cutlass
- OpenAI Triton 文档:triton-lang.org
- AMD ROCm Documentation,rocm.docs.amd.com
- Intel oneAPI Programming Guide,intel.com/content/www/us/en/developer/tools/oneapi
- 深度学习框架集成相关:PyTorch 官方 cuDNN 后端文档,TensorRT Developer Guide。
注:凡涉及精确硬件数量(如 SM 数量、缓存大小、具体 TFLOPS 值)的市场讨论,请以对应产品厂商最新公开数据为准,本文仅做定性技术原理解析。