GPU硬件架构

阶段2 | 第9-12周

📅 4周详细学习计划

第9周:SM架构基础

• SM内部结构
• CUDA Core工作原理
• 寄存器文件
• 调度器机制

第10周:Warp与执行模型

• Warp调度策略
• 分支发散分析
• Warp协作通信
• __shfl_sync使用

第11周:Tensor Core

• MMA操作原理
• FP16/INT8计算
• WMMA API使用
• CUTLASS库

第12周:显存与互联

• HBM/GDDR区别
• L2 Cache策略
• NVLink带宽
• 多卡通信基础

1. SM (Streaming Multiprocessor) 架构

┌─────────────────────────────────────────────────────────────┐ │ GPU (e.g., A100) │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ SM 0 │ │ SM 1 │ │ SM 2 │ │ SM 108 │ │ │ │┌───────┐│ │ │ │ │ │ │ │ │ ││1024 ││ │ ... │ │ ... │ │ ... │ │ │ ││CUDA ││ │ │ │ │ │ │ │ │ ││Cores ││ │ │ │ │ │ │ │ │ │├───────┤│ │ │ │ │ │ │ │ │ ││4Tensor││ │ │ │ │ │ │ │ │ ││Cores ││ │ │ │ │ │ │ │ │ │├───────┤│ │ │ │ │ │ │ │ │ ││256KB ││ │ │ │ │ │ │ │ │ ││Shared ││ │ │ │ │ │ │ │ │ ││+L1 ││ │ │ │ │ │ │ │ │ │└───────┘│ │ │ │ │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ ┌─────────────┐ │ │ │ 40MB L2 │ │ │ └─────────────┘ │ │ ┌─────────────┐ │ │ │ 80GB HBM │ │ │ └─────────────┘ │ └─────────────────────────────────────────────────────────────┘

1.1 SM核心组件

1.2 SM工作原理

2. Warp执行模型

Block (256 threads = 8 Warps) ┌─────────────────────────────────────┐ │ Warp 0: Thread 0-31 │ ← 32线程,SIMT执行 │ Warp 1: Thread 32-63 │ │ Warp 2: Thread 64-95 │ │ ... │ │ Warp 7: Thread 224-255 │ └─────────────────────────────────────┘ 分支发散示例: if (threadIdx.x % 2 == 0) do_A(); // 偶数线程执行 else do_B(); // 奇数线程执行 结果:Warp串行执行两个分支,性能下降50%

2.1 Warp调度

2.2 分支发散 (Branch Divergence)

// ❌ 分支发散
if (threadIdx.x < 16) {
    do_something_A();  // 前16个线程执行
} else {
    do_something_B();  // 后16个线程执行
}

// ✅ 避免发散 - 使用掩码
unsigned int mask = (threadIdx.x < 16) ? 0xFFFF : 0x0000;
// 使用__ballot_sync()获取线程投票

2.3 Warp协作通信

// Warp Shuffle实现归约
__device__ float warp_reduce_sum(float val) {
    for (int offset = 16; offset > 0; offset >>= 1) {
        val += __shfl_down_sync(0xFFFFFFFF, val, offset);
    }
    return val;
}

3. Occupancy(占用率)详解

// Occupancy计算示例 (A100)
// A100: 每SM 2048线程, 64个Warp, 65536寄存器

// Case 1: 低寄存器使用
// 每线程32寄存器 → 2048*32=65536 → 100% Occupancy

// Case 2: 高寄存器使用
// 每线程64寄存器 → 1024*64=65536 → 50% Occupancy

// 使用__launch_bounds__控制寄存器
__global__ void __launch_bounds(256, 2)  // maxThreadsPerBlock=256, minBlocksPerSM=2
my_kernel() {
    // 编译器会优化寄存器使用以达到目标Occupancy
}

4. Tensor Core详解

Tensor Core MMA (Matrix Multiply-Accumulate) ┌─────────────────────────────────────────┐ │ D = A × B + C │ │ │ │ A: 16×16 matrix (FP16) │ │ B: 16×16 matrix (FP16) │ │ C: 16×16 matrix (FP32) │ │ D: 16×16 matrix (FP32) │ │ │ │ 一条指令完成 16×16×16 = 4096 次FMA │ └─────────────────────────────────────────┘

4.1 Tensor Core支持的精度

4.2 WMMA API使用

// WMMA (Warp Matrix Multiply Accumulate) 示例
#include <mma.h>

using namespace nvcuda;

__global__ void tensor_core_gemm(half *A, half *B, float *C) {
    // 声明片段
    wmma::fragment<wmma::matrix_a, 16, 16, 16, half, wmma::row_major> a_frag;
    wmma::fragment<wmma::matrix_b, 16, 16, 16, half, wmma::col_major> b_frag;
    wmma::fragment<wmma::accumulator, 16, 16, 16, float> c_frag;
    
    // 加载矩阵
    wmma::load_matrix_sync(a_frag, A, 16);
    wmma::load_matrix_sync(b_frag, B, 16);
    
    // 执行矩阵乘加
    wmma::mma_sync(c_frag, a_frag, b_frag, c_frag);
    
    // 存储结果
    wmma::store_matrix_sync(C, c_frag, 16, wmma::mem_row_major);
}

5. 显存层次详解

内存类型容量(A100)带宽延迟用途
Registers每线程255个极高(无限)1周期局部变量,中间结果
Shared Memory164KB/SM~19TB/s~5周期线程协作,数据复用
L1 Cache92KB/SM~19TB/s~30周期全局数据缓存
L2 Cache40MB~5TB/s~200周期全局数据缓存
HBM2e80GB2TB/s400-800周期全局数据存储

5.1 HBM vs GDDR

6. NVLink / NVSwitch

📚 学习资源

🛠️ 实践项目