4. GPU核心概念

在DPU/GPU与NVLink集群互联的体系中,GPU并不是一块“插在PCIe槽里的加速卡”这么简单。要理解NVLink为什么重要、DPU为什么能卸载通信、集群为什么能线性扩展,必须先回到GPU自身的核心概念:它由哪些硬件层次构成、线程如何被调度、数据在显存层次中如何流动、并行计算模型如何映射到硬件,以及哪些场景真正适合GPU加速。本节把这些概念串成一条从硬件到应用的完整链路。

一、GPU架构:从SM阵列到存储层次

现代GPU(以NVIDIA Ampere/Hopper架构为代表)在宏观上由若干GPC(图形处理集群)组成,每个GPC内部包含多个SM(Streaming Multiprocessor,流式多处理器)。SM是GPU真正执行计算的基本单元,内部又包含CUDA核心、Tensor Core、RT Core、寄存器文件、共享内存/L1缓存、Warp调度器等部件。GPU与CPU最大的结构差异在于:CPU用少量大核追求低延迟和复杂控制,GPU用成百上千个轻量核心追求高吞吐,把“等待内存”的时间用其他Warp的计算填满。

因此GPU架构可以概括为三层:计算层(GPC→SM→CUDA Core/Tensor Core)、存储层(寄存器→共享内存/L1→L2→显存)、调度层(Grid→Block→Warp→Thread)。NVLink和DPU所解决的,正是最外层“显存与显存之间、GPU与GPU之间”的数据搬运瓶颈。

GPU 架构与显存层次总览 GPC(图形处理集群) SM 流式多处理器 CUDA Core 阵列 FP32 / INT32 并行 Tensor Core 矩阵乘加加速 Warp 调度器 32 线程/组 寄存器 / 共享内存 片上高速存储 显存层次(由快到慢) 寄存器 Register(最快,线程私有) 共享内存 / L1(Block 内共享) L2 缓存(全 GPU 共享) HBM 显存(容量大,带宽高) 跨 GPU:NVLink / PCIe / 网络 访问 并行计算模型映射:Grid → Block → Warp → Thread Grid 整个内核任务 Block 映射到一个 SM Warp 32 线程同步执行 Thread 最小执行单元

二、CUDA核心与Tensor Core:两种算力的分工

CUDA核心是通用标量/向量运算单元,擅长逐元素计算、分支逻辑、地址计算和各类非规则运算。Tensor Core则是为矩阵乘加(D = A×B + C)设计的专用单元,在FP16/BF16/FP8/INT8等低精度格式下提供数量级更高的吞吐。二者并非替代关系:一个典型的Transformer推理内核,既用Tensor Core完成QKV投影和FFN矩阵乘,也用CUDA核心完成LayerNorm、Softmax、激活和索引搬运。

理解这一点对集群互联很关键:Tensor Core算得越快,单位时间需要喂入的数据就越多,显存带宽和GPU间带宽就越容易成为瓶颈。这正是NVLink把GPU间带宽提升到数百GB/s量级的根本动因。

三、显存层次与访存优化

GPU的存储层次从快到慢依次为:寄存器、共享内存/L1、L2、HBM显存,再往外是跨GPU的NVLink/PCIe和网络。编写高性能内核的核心思路是提高数据复用、减少对HBM的重复访问。常见手段包括:把频繁访问的小块数据放入共享内存、让相邻线程访问相邻地址以实现合并访存、通过分块(Tiling)让同一份数据被多次计算复用。

判断一个内核是“计算受限”还是“访存受限”,可以看它的算术强度(每字节数据对应的浮点运算次数)。算术强度低的内核,即使CUDA核心空闲,性能也被显存带宽锁死。

四、并行计算模型与执行流程

CUDA的并行模型是“单程序多数据”的层次化映射:主机端启动一个Grid,Grid由多个Block组成,Block由多个线程组成,硬件把每32个线程打包成一个Warp交给SM调度。Block之间不能保证执行顺序,因此跨Block同步必须靠多次内核启动或原子操作完成。

// 向量加法:Grid/Block/Thread 三层映射示例
__global__ void vecAdd(const float* a, const float* b, float* c, int n) {
    int i = blockIdx.x * blockDim.x + threadIdx.x;  // 全局线程索引
    if (i < n) c[i] = a[i] + b[i];
}

int main() {
    int n = 1 << 20;
    int threadsPerBlock = 256;
    int blocksPerGrid = (n + threadsPerBlock - 1) / threadsPerBlock;
    vecAdd<<<blocksPerGrid, threadsPerBlock>>>(a, b, c, n);
    cudaDeviceSynchronize();
}

执行流程可归纳为:主机分配显存并拷贝数据 → 启动内核 → SM 调度 Warp 并隐藏访存延迟 → 结果拷回主机。在多卡场景中,中间还会插入NVLink点对点传输或DPU参与的通信卸载。

五、典型加速场景与选型对照

GPU并非万能。它适合“数据并行度高、算术密集、分支少”的任务,不适合强串行、频繁随机小访问、控制逻辑复杂的任务。下表给出常见场景的匹配度参考。

应用场景 主要算力单元 关键瓶颈 加速收益
深度学习训练Tensor CoreGPU间梯度同步极高
大模型推理Tensor Core + CUDA Core显存带宽、KV Cache高
科学计算(CFD/分子动力学)CUDA Core(FP64)双精度吞吐、通信高
视频编解码与图像处理专用编解码单元 + CUDA Core显存带宽中高
数据库扫描与聚合CUDA Core随机访存、分支中
强串行事务逻辑CPU 更合适控制依赖低

六、常见误区与复盘要点

  • 误区一:核心越多越快。实际性能取决于访存模式、占用率和指令混合,核心数只是上限。
  • 误区二:忽略Warp分歧。同一Warp内线程走不同分支会串行化,显著拉低效率。
  • 误区三:只优化单卡。在多卡集群中,通信往往占据30%以上时间,必须结合NVLink拓扑和DPU卸载一起设计。
  • 复盘要点:先用Nsight Compute确认是计算受限还是访存受限,再决定优化方向;跨卡场景先看通信占比,再决定是否启用NVLink聚合或DPU卸载。
一句话总结:GPU架构提供海量并行算力,CUDA核心与Tensor Core分工承担通用与矩阵计算,显存层次决定数据能多快被喂入,并行计算模型决定这些算力能否被有效调度;而NVLink与DPU,则是在单卡算力被充分释放后,把这种能力扩展到整个集群的关键一环。