CUDA核心是GPU中执行通用计算的基本运算单元,每个核心包含整数与浮点ALU。成千上万个CUDA核心通过SIMT架构并行执行线程束,为深度学习的矩阵运算提供大规模并行算力。文章从核心微架构、线程调度到指令执行流水线,剖析CUDA核心的工作原理与性能特性。
需要学习CUDA核心,CUDA核心是GPU中执行通用计算的基本运算单元,每个核心包含整数与浮点ALU。在AI芯片架构 > GPU架构的学习路径中,CUDA核心直接影响对深层原理的理解。
目录
可视化演示
通过核心微架构、SIMT线程束执行与矩阵运算并行三模式,展示GPU CUDA核心的工作原理与性能特性。
本节配有交互动效(进入视口后自动加载,约 3KB)。
CUDA核心微架构 每个CUDA核心包含INT ALU与FP32 FPU,五级流水线执行指令 IPC=FLOPS/(Freq×Cores) 核心微架构是GPU并行算力的基础单元
CUDA核心的基本架构与运算单元组成
CUDA核心是NVIDIA GPU中最基础的标量运算单元,位于流多处理器(SM)内部。每个CUDA核心包含整数运算单元(INT ALU)和浮点运算单元(FP ALU)。从Turing架构起,NVIDIA将FP32与INT32单元物理分离,使CUDA核心可在同一周期内并行发射一条浮点和一条整数指令,显著提升指令级并行度,对同时涉及地址计算与数据运算的循环尤为有利。
在浮点运算方面,CUDA核心支持FMA(融合乘加)指令,单条指令完成a*b+c且仅一次舍入,精度高于先乘后加。FP32单元是主力,每周期可完成一次FP32 FMA;数据中心GPU(如A100)每个SM还配备FP64单元支持双精度科学计算。CUDA核心处理标量运算,矩阵乘加则交给专用Tensor Core,二者协同完成深度学习计算图中的不同算子。
SIMT架构——单指令多线程的并行执行模型
SIMT(单指令多线程)是NVIDIA GPU的核心执行模型,介于SIMD与MIMD之间。与SIMD将数据打包成向量同步操作不同,SIMT中每个线程拥有独立的程序计数器(PC)和寄存器状态,理论上可各自走向不同执行路径。硬件以warp为单位分组调度线程,程序员仍可像编写单线程程序一样编写kernel,由硬件自动汇聚并行性。
SIMT的线程独立性带来灵活性,也引入warp divergence(分支发散)问题:同一warp内线程因条件判断走向不同分支时,硬件需串行执行各路径,并通过执行掩码禁用非活跃线程的写操作,导致利用率下降。Volta架构起引入独立线程调度,为每个线程维护独立PC,使发散线程能各自推进并在显式同步点收敛,缓解了pre-Volta架构下整warp空转的低效。
线程束(Warp)——CUDA核心的调度执行单元
Warp(线程束)是GPU硬件调度的最小单元,固定包含32个线程。程序员以线程块(Block)组织线程,但硬件自动将每个块按32线程一组划分为warp调度执行。warp内32线程共享同一条指令,由SM内的warp调度器统一发射。由于warp是调度原子单位,单个线程无法独立调度,block线程总数通常建议设为32的倍数以避免末尾warp活跃线程不足。
SM通常同时驻留多个活跃warp(如A100每SM最多48个warp),warp调度器每周期从就绪warp中选择一个发射指令。由于所有活跃warp的上下文(PC、寄存器等)都常驻在寄存器文件中,切换warp无需保存和恢复状态,故称零开销线程束切换。这是GPU隐藏长延迟操作的核心手段:warp停顿时立即切换到其他就绪warp,保持高吞吐。
指令执行流水线——从取指到写回的完整过程
CUDA核心的指令执行遵循典型流水线流程,包括取指(Fetch)、译码(Decode)、执行(Execute)和写回(WriteBack)等阶段。取指从指令缓存读取warp当前PC指向的指令;译码解析操作码与操作数;执行将指令派发到对应功能单元(FP ALU、INT ALU、加载存储单元等)运算;写回将结果写回寄存器文件。现代GPU的SM每周期可向不同子单元发射多条指令,通过指令级并行提升吞吐。
流水线执行中,长延迟操作(如全局内存加载需数百周期)会阻塞warp。GPU不依赖乱序执行或分支预测掩盖延迟,而依靠延迟隐藏(warp switching):warp因等待操作数停顿时,调度器切换到其他就绪warp发射指令。只要SM驻留的活跃warp足够多,使独立指令能填满延迟周期,计算单元即可保持繁忙,这正是高occupancy有助于性能的原因。
CUDA核心的存储层次与数据访问模式
CUDA核心所处的存储层次从快到慢依次为:寄存器、共享内存、L1缓存、L2缓存和全局显存。寄存器是每线程私有、延迟最低(约1周期)的存储;共享内存位于SM片上SRAM,与L1共享物理资源,由程序员显式管理,延迟约30周期,是block内线程通信与数据复用的关键。L1/L2为硬件自动管理缓存,L2为所有SM共享;全局显存容量最大但延迟最高(约400-800周期)。
高效利用存储层次是CUDA优化的核心。对全局内存访问应满足合并访问(coalesced access)条件——warp内32线程访问连续且对齐的地址,使硬件将多次访问合并为少量128字节事务,否则产生额外事务降低带宽。共享内存划分为32个bank,warp内多线程访问同一bank的不同地址会产生bank conflict导致串行化;访问同一地址则广播无冲突,合理布局(如padding)可避免冲突。
CUDA核心在深度学习矩阵运算中的加速原理
深度学习的核心运算是矩阵乘法(GEMM),其天然具备高度数据并行性。CUDA通过将输出矩阵每个元素的计算分配给不同线程,并将行/列遍历维度并行化,使海量CUDA核心同时工作。例如对C=A×B,可将C的每个元素交给一个线程计算内积,或将矩阵分块(tiling)后用共享内存缓存A、B的子块,减少对全局内存的重复访问。这种分块策略能显著提升数据复用率,是cuBLAS等库获得高算力的关键。
尽管CUDA核心能执行矩阵运算,但深度学习主力是Tensor Core——专用矩阵乘加单元,单周期完成16×8×16小矩阵D=A×B+C,吞吐远超CUDA核心。二者分工:GEMM由Tensor Core加速,激活、归一化、逐元素运算等仍由CUDA核心执行。性能还依赖occupancy(活跃warp数与SM最大warp数之比),受每线程寄存器量和每block共享内存量制约,需权衡寄存器压力与并发度。
CUDA核心的演进与未来发展趋势
CUDA核心随架构代际演进:Turing将FP32与INT32单元分离实现同周期并行;Ampere提升每SM的FP32吞吐(可配64条FP32或32+32 INT32每周期),引入TF32、BF16与第三代Tensor Core;Hopper带来Transformer Engine、TMA与Cluster,原生支持FP8及warp group。演进在保持通用性的同时强化低精度与异步能力。
面向未来,Blackwell以第五代Tensor Core原生支持FP4/FP8,低精度推理吞吐再翻倍。趋势上,CUDA核心从单一通用单元转向与Tensor Core、TMA等专用单元协同:通过warp specialization让不同warp分别承担搬运与计算,构建生产者-消费者异步流水线;DSM和集群机制扩展block间协作。整体是在保持SIMT简洁性的同时,以专用化与异步化榨取更高能效。
AI 应用场景
深度学习模型训练的GPU并行加速
阶段:模型训练
解决的问题:大模型训练中矩阵乘法计算量巨大,单靠CPU无法在合理时间内完成,需要利用GPU海量CUDA核心与Tensor Core进行大规模并行加速。
具体案例:训练一个Transformer大模型时,前向传播中的注意力与MLP层都是大规模GEMM,cuBLAS将矩阵分块后分配给SM上的CUDA核心与Tensor Core并行计算,配合共享内存缓存权重子块复用数据,使单卡每秒完成数十万亿次FMA运算,将原本数月的训练压缩到数天。
AI推理实时计算加速
阶段:推理优化
解决的问题:在线推理要求低延迟高吞吐,需要通过warp调度、低精度计算与算子融合让GPU CUDA核心与Tensor Core高效协作以满足SLA。
具体案例:部署LLM推理服务时,使用FP8/INT8量化让Tensor Core高吞吐执行GEMM,同时CUDA核心并行处理LayerNorm、激活函数等逐元素算子,再通过warp specialization让一组warp搬运KV Cache、另一组计算,实现访存与计算重叠,将首token延迟降至几十毫秒。
科学计算数值模拟
阶段:模型部署
解决的问题:CFD、分子动力学等科学计算需要高精度双精度浮点与大规模并行,依赖GPU的FP64 CUDA核心与高带宽显存完成海量迭代计算。
具体案例:在分子动力学模拟中,每步需计算数百万粒子间的非键相互作用,使用A100的FP64 CUDA核心并行计算每个粒子受力,通过共享内存缓存邻居列表分块复用,配合零开销warp切换隐藏全局内存延迟,使单日模拟时长从纳秒级提升到微秒级,加速药物筛选流程。
Python 演示
import numpy as np class Warp: def __init__(self, warp_id, size=32): self.warp_id = warp_id self.size = size self.pc = 0 self.active = [True] * size self.regs = [0.0] * size def fma(self, a, b, c): out = [] for t in range(self.size): if self.active[t]: out.append(a[t] * b[t] + c[t]) else: out.append(None) self.pc += 1 return out def branch(self, cond): for t in range(self.size): self.active[t] = cond(t) class WarpScheduler: def __init__(self, warps): self.warps = warps self.cycle = 0 def step(self): warp = self.warps[self.cycle % len(self.warps)] a = [float(t) for t in range(warp.size)] b = [2.0] * warp.size c = [1.0] * warp.size res = warp.fma(a, b, c) active = sum(1 for x in res if x is not None) print(f"cycle {self.cycle} warp {warp.warp_id} pc {warp.pc} active {active}") self.cycle += 1 def sim_matmul(n): A = np.random.rand(n, n) B = np.random.rand(n, n) C = np.zeros((n, n)) for i in range(n): for j in range(n): for k in range(n): C[i, j] += A[i, k] * B[k, j] return C warps = [Warp(i) for i in range(4)]warps[1].branch(lambda t: t % 2 == 0)sched = WarpScheduler(warps)for _ in range(8): sched.step()print("matmul result:", sim_matmul(4)[0, 0])
import numpy as np导入numpy用于后续矩阵乘法模拟,对应GPU上的GEMM运算。class Warp:定义Warp类,模拟CUDA线程束(默认32线程)及其PC、寄存器与活跃掩码状态。def __init__(self, warp_id, size=32):初始化warp,size默认为32,对应NVIDIA硬件固定的warp大小。self.active = [True] * size用布尔列表标记每个线程是否活跃,模拟SIMT的执行掩码机制。def fma(self, a, b, c):模拟FMA融合乘加指令,对warp内活跃线程执行a*b+c运算。out.append(a[t] * b[t] + c[t])对活跃线程计算FMA结果,非活跃线程返回None模拟被掩码禁用。self.pc += 1程序计数器递增,模拟指令执行完毕后PC推进到下一条指令。def branch(self, cond):模拟条件分支,根据cond函数更新活跃掩码从而产生warp发散。warp = self.warps[self.cycle % len(self.warps)]warp调度器按周期轮转选择一个warp发射指令,模拟零开销warp切换。res = warp.fma(a, b, c)对选定的warp执行FMA指令并收集各线程结果,统计活跃线程数。def sim_matmul(n):模拟并行矩阵乘法,展示CUDA核心如何将GEMM分解为标量FMA循环。C[i, j] += A[i, k] * B[k, j]矩阵乘法核心累加内积,对应单个CUDA核心执行的一条标量FMA指令。warps[1].branch(lambda t: t % 2 == 0)让warp 1仅偶数线程活跃,演示条件分支导致的warp发散与利用率下降。sched.step()每个周期调度一个warp执行指令,循环8次模拟warp调度器的轮转执行过程。
常见问答
CUDA核心和Tensor Core有什么区别?
为什么一个warp是32个线程而不是其他数量?
什么是occupancy,是否越高越好?
Warp divergence(分支发散)如何影响性能,如何缓解?
常见误区
误区CUDA核心数量越多,GPU性能就线性提升。
正解性能取决于计算、访存带宽、Tensor Core、缓存及调度能力的综合平衡,核心数只是其中一项。核心多但显存带宽不足或occupancy偏低时,性能无法线性扩展,还可能受memory wall制约。
误区CPU的ALU和GPU的CUDA核心本质相同。
正解CPU ALU为低延迟深度流水线设计,强调单线程性能与复杂分支预测、大缓存;CUDA核心面向高吞吐,以warp为单位SIMT调度,无复杂分支预测,依赖大量线程并行隐藏延迟,设计哲学截然不同。
误区warp越大,并行效率越高。
正解warp大小固定为32,并非越大越好。过大会加剧分支发散的浪费、增加调度与寄存器压力;32是与存储bank和调度宽度匹配的平衡值,且不可配置,增大warp并不会提升效率。
误区GPU只有Tensor Core重要,CUDA核心可以忽略。
正解Tensor Core只能加速矩阵乘加,而激活函数、归一化、逐元素运算、控制流等仍需CUDA核心执行。若CUDA核心成为瓶颈(如RNN/LSTM中的门控运算),整体性能同样受限,二者需协同优化。
参考来源
- docCUDA C++ Programming GuideNVIDIA官方编程指南,定义了SIMT执行模型、warp调度、线程层次(Grid/Block/Warp/Thread)及存储层次(寄存器、共享内存、L1/L2、全局内存)等核心概念。
- docParallel Thread Execution ISA (PTX)PTX指令集参考文档,涵盖MMA矩阵指令、cp.async异步拷贝、warp shuffle原语、寄存器分配粒度及缓存修饰符(.ca/.cg/.cs)等CUDA核心底层执行细节。
- paperNVIDIA Ampere Architecture WhitepaperAmpere架构白皮书,给出A100每SM的64个FP32 CUDA核心、65536个寄存器、192KB可配置SRAM、第三代Tensor Core及TF32/BF16支持等技术规格。
- docNVIDIA Hopper ArchitectureHopper架构介绍,涵盖Transformer Engine、TMA张量内存加速器、Thread Block Clusters、分布式共享内存(DSM)、FP8支持及warp group等CUDA核心演进特性。