跳转至

第16章 §01 · SIMD 与 GPU 编程总览 · 讲解稿

章节定位: Ch16 §00 总览 → §01 硬件基础 承接: Ch13 计算机架构 + Ch17 AI 推理 (前置依赖) 篇幅: ~5500 字 / 阅读 14 分钟 / 讲解 28 分钟


一 · 一句话总览

SIMD/GPU = 硬件加速的"屠龙刀"。理解 CPU SIMD (AVX/NEON) + GPU (CUDA/Triton) 是性能工程师的"分水岭"。


二 · 心智模型

把计算想象成工人搬砖: - CPU 单线程: 1 个工人搬 1 块砖 → 慢但灵活 - CPU SIMD: 1 个工人同时搬 4 块砖 (AVX-256) → 快 4 倍 - GPU 1000 线程: 1000 个工人同时搬砖 → 快 1000 倍 (但要能并行) - TPU 矩阵单元: 1 个超大工人一次搬 128×128 砖 → 块大但密集

核心: 数据并行 = 性能。


三 · 章节主线 (5 段)

第 1 段 · SIMD 基础 (8 分钟)

3.1.1 什么是 SIMD

SIMD = Single Instruction Multiple Data, 单指令多数据: - 1 个指令操作多个数据 (4 / 8 / 16 / 32 个同时) - 寄存器宽度: 128 (SSE) → 256 (AVX) → 512 (AVX-512) - 1 个 AVX-512 寄存器 = 16 个 FP32

3.1.2 主流 SIMD 指令集

指令集 厂商 宽度 状态
SSE / SSE2/3/4 Intel/AMD 128-bit 旧
AVX / AVX2 Intel/AMD 256-bit 主流
AVX-512 Intel 512-bit 服务器
NEON ARM 128-bit 移动
SVE / SVE2 ARM 128-2048 服务器
RISC-V V 开源 可变 新兴

3.1.3 SIMD 编程模型

// 标量
for (int i = 0; i < n; i++) {
    c[i] = a[i] + b[i];
}

// SIMD (intrinsics)
__m256 va = _mm256_load_ps(a);
__m256 vb = _mm256_load_ps(b);
__m256 vc = _mm256_add_ps(va, vb);
_mm256_store_ps(c, vc);

第 2 段 · GPU 架构 (10 分钟)

3.2.1 CPU vs GPU

指标 CPU GPU
核心数 4-64 1000-10000
频率 3-5 GHz 1-2 GHz
缓存 MB KB
适用 顺序 / 串行 数据并行
能耗 中 高
内存 DDR HBM (大)

3.2.2 NVIDIA GPU 架构

SM (Streaming Multiprocessor) = GPU 的核心: - 1 SM = 64-128 CUDA 核心 - Ampere (A100): 108 SM × 64 core = 6912 cores - Hopper (H100): 132 SM × 128 core = 16896 cores - 每个 SM 有共享内存 + Tensor Core

3.2.3 Memory Hierarchy

Register (per thread)     ~ns      ~32 KB/SM
Shared Memory (per block) ~10 ns   ~100 KB/SM
L1 Cache (per SM)         ~20 ns   ~128 KB/SM
L2 Cache (per GPU)        ~100 ns  ~50 MB
HBM (global)              ~500 ns  40-80 GB (A100/H100)
Host Memory (DMA)         ~μs      TB

3.2.4 CUDA 编程模型

__global__ void vector_add(float *a, float *b, float *c, int n) {
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    if (idx < n) c[idx] = a[idx] + b[idx];
}

int main() {
    int n = 1024 * 1024;
    int threads = 256;
    int blocks = (n + threads - 1) / threads;
    vector_add<<<blocks, threads>>>(a, b, c, n);
    cudaDeviceSynchronize();
}

第 3 段 · 高级 GPU 优化 (12 分钟)

3.3.1 Memory Coalescing

核心: 连续线程访问连续内存 → 1 次 transaction。

线程 0-31 访问 addr[0..127] → 1 个 128B 事务 (合并) ✓
线程 0-31 访问 addr[0, 32, 64, ...] → 32 个事务 (不合并) ✗

3.3.2 Shared Memory Bank Conflict

Shared memory 分 32 bank: - 同 bank 不同地址 → conflict (串行) - 不同 bank → 并行

__shared__ float sm[32][32];
// 访问 sm[tid][0] for tid in 0..31 → 全 bank 0 → 31 个 conflict
// 解决: sm[tid][tid] (对角)

3.3.3 Occupancy

Occupancy = 活跃 warp 数 / 最大 warp 数: - 受 register / shared mem 限制 - 一般 50%+ 即可 - 工具: nvcc --ptxas-options=-v

3.3.4 Tensor Core

矩阵乘加速器: - A100: TF32 156 TFLOPS, FP16 312 TFLOPS - H100: FP8 3.3 PFLOPS, FP16 1.9 PFLOPS - 调用: mma.sync.aligned.m16n8k16.row.col.f32.tf32.tf32.f32

第 4 段 · Triton 入门 (10 分钟)

3.4.1 Triton 是什么

Triton = Pythonic GPU 编程语言 (OpenAI 2021): - 比 CUDA 简单 (Python 风格) - 自动优化 (memory coalescing / 共享内存) - 编译为 PTX (NVIDIA GPU)

3.4.2 Triton 编程示例

import triton
import triton.language as tl

@triton.jit
def add_kernel(x_ptr, y_ptr, out_ptr, n, BLOCK: tl.constexpr):
    pid = tl.program_id(0)
    offset = pid * BLOCK + tl.arange(0, BLOCK)
    mask = offset < n
    x = tl.load(x_ptr + offset, mask=mask)
    y = tl.load(y_ptr + offset, mask=mask)
    tl.store(out_ptr + offset, x + y, mask=mask)

def add(x, y):
    out = torch.empty_like(x)
    n = x.numel()
    BLOCK = 1024
    grid = (triton.cdiv(n, BLOCK),)
    add_kernel[grid](x, y, out, n, BLOCK=BLOCK)
    return out

3.4.3 Triton vs CUDA

维度 Triton CUDA
易用性 ✅ Python ❌ C++
性能 80-95% SOTA 100% SOTA
控制粒度 中 极细
适用 算子实现 / Kernel 优化 极致优化

第 5 段 · 实战案例 (8 分钟)

3.5.1 案例 1: 矩阵乘 SIMD

// AVX-512 8x8 矩阵乘
void matmul_avx512(const float *A, const float *B, float *C, int M, int N, int K) {
    for (int i = 0; i < M; i += 8) {
        for (int j = 0; j < N; j += 16) {
            __m512 c[8] = {_mm512_setzero_ps(), ...};
            for (int k = 0; k < K; k++) {
                __m512 b = _mm512_loadu_ps(&B[k * N + j]);
                for (int ii = 0; ii < 8; ii++) {
                    __m512 a = _mm512_set1_ps(A[i * K + ii * K + k]);
                    c[ii] = _mm512_fmadd_ps(a, b, c[ii]);
                }
            }
            for (int ii = 0; ii < 8; ii++) _mm512_storeu_ps(&C[(i+ii)*N + j], c[ii]);
        }
    }
}

3.5.2 案例 2: Softmax CUDA Kernel

__global__ void softmax_kernel(const float *in, float *out, int n) {
    extern __shared__ float smem[];
    int tid = threadIdx.x;
    int gid = blockIdx.x * blockDim.x + tid;

    // 1. 找 max
    float max_val = -INFINITY;
    if (gid < n) max_val = in[gid];
    smem[tid] = max_val;
    __syncthreads();
    for (int s = blockDim.x / 2; s > 0; s >>= 1) {
        if (tid < s) smem[tid] = max(smem[tid], smem[tid + s]);
        __syncthreads();
    }
    float block_max = smem[0];

    // 2. exp & sum
    float exp_val = (gid < n) ? expf(in[gid] - block_max) : 0;
    smem[tid] = exp_val;
    __syncthreads();
    for (int s = blockDim.x / 2; s > 0; s >>= 1) {
        if (tid < s) smem[tid] += smem[tid + s];
        __syncthreads();
    }
    float sum = smem[0];

    // 3. divide
    if (gid < n) out[gid] = exp_val / sum;
}

四 · 关键论文 / 工具

工具 出品 用途
CUDA Toolkit NVIDIA GPU 编程
Triton OpenAI Pythonic GPU
rocPRIM / HIP AMD AMD GPU
oneAPI / SYCL Intel 跨厂商
Numba Continuum Python JIT

五 · 跨章连接

章节 关联
Ch13 §02 CPU 架构
Ch17 §01 量化
Ch17 §02 高效架构 (Flash Attention)
Ch18 §03 分布式 GPU

六 · 自测 5 题

  1. SIMD 与 SIMT 区别?
  2. 什么是 Memory Coalescing?
  3. Tensor Core 主要用于?
  4. Triton 相对 CUDA 的优势?
  5. SM 与 CUDA Core 关系?

七 · 一句话总结

SIMD/GPU = 数据并行的硬件加速。AVX-512 加速 CPU 4-16 倍, GPU 加速 100-1000 倍, Triton 让 GPU 编程平民化。理解 memory hierarchy + coalescing + occupancy = 性能优化基础。