chip_packaging_interconnect

第15章:近存储计算架构

章节概述

本章深入探讨近存储计算(Processing-in-Memory, PIM)和近数据处理(Processing-near-Data, PND)架构,这是解决”内存墙”问题的革命性方案。我们将分析如何通过将计算单元集成到内存系统中,大幅减少数据移动开销,提升系统能效比。重点介绍Samsung HBM-PIM、SK Hynix AiM等工业界先进实现,以及在AI推理、图计算等应用中的实践。

学习目标:

15.1 PIM概念与发展历程

15.1.1 内存墙问题的本质

过去几十年,处理器性能以每年约60%的速度增长,而DRAM访问延迟仅以每年7%的速度改善。这种差距导致了严重的”内存墙”问题:

性能差距 = (1.6)^n / (1.07)^n ≈ (1.5)^n
其中n为年数

数据移动能耗已成为系统功耗的主要来源:

15.1.2 PIM架构分类

1. 真PIM(True PIM) 将逻辑单元直接集成在存储阵列内部:

  ┌──────────────────────────┐
  │   Memory Array           │
  │  ┌────┬────┬────┬────┐  │
  │  │Cell│Cell│Cell│Cell│  │
  │  ├────┼────┼────┼────┤  │
  │  │ ALU│ ALU│ ALU│ ALU│  │ ← 计算单元
  │  ├────┼────┼────┼────┤  │
  │  │Cell│Cell│Cell│Cell│  │
  │  └────┴────┴────┴────┘  │
  │       Sense Amplifiers   │
  └──────────────────────────┘

2. 近数据处理(PND) 在内存控制器或基础逻辑层集成计算单元:

  ┌──────────────────────────┐
  │   DRAM Die Stack         │
  ├──────────────────────────┤
  │   Through Silicon Vias   │
  ├──────────────────────────┤
  │   Logic Base Die         │ ← 计算层
  │  ┌─────────────────────┐ │
  │  │ Processing Units    │ │
  │  │ Cache & Controllers │ │
  │  └─────────────────────┘ │
  └──────────────────────────┘

15.1.3 PIM发展历程

第一代(1990s):

第二代(2000s):

第三代(2010s-至今):

15.2 Samsung HBM-PIM架构详解

15.2.1 系统架构

Samsung HBM-PIM在HBM2 Aquabolt基础上,在每个伪通道(Pseudo Channel)集成了一个SIMD处理单元:

  ┌─────────────────────────────────────┐
  │         Host Processor              │
  ├─────────────────────────────────────┤
  │         Memory Controller           │
  └────────┬───────────────────┬────────┘
           │   1024-bit Bus    │
  ┌────────▼───────────────────▼────────┐
  │           HBM-PIM Stack              │
  │  ┌──────────────────────────────┐   │
  │  │    DRAM Die 7 (4GB)          │   │
  │  ├──────────────────────────────┤   │
  │  │    DRAM Die 6 (4GB)          │   │
  │  ├──────────────────────────────┤   │
  │  │    ...                       │   │
  │  ├──────────────────────────────┤   │
  │  │    DRAM Die 0 (4GB)          │   │
  │  ├──────────────────────────────┤   │
  │  │    Buffer/Logic Die          │   │
  │  │  ┌────────────────────────┐  │   │
  │  │  │  16 × PIM Units        │  │   │
  │  │  │  (2 per PC)            │  │   │
  │  │  └────────────────────────┘  │   │
  │  └──────────────────────────────┘   │
  └─────────────────────────────────────┘

15.2.2 PIM单元微架构

每个PIM单元包含:

PIM Unit微架构:
  ┌─────────────────────────────────┐
  │         To Memory Banks         │
  └────────────┬────────────────────┘
               │ 256-bit
  ┌────────────▼────────────────────┐
  │      Data Buffer (2KB)          │
  ├─────────────────────────────────┤
  │   ┌─────────┐  ┌─────────┐     │
  │   │  FP16   │  │  INT8   │     │
  │   │  MAC    │  │  ALU    │     │
  │   └────┬────┘  └────┬────┘     │
  │        │            │           │
  │   ┌────▼────────────▼────┐     │
  │   │  Register File (8×)   │     │
  │   └───────────────────────┘     │
  ├─────────────────────────────────┤
  │    Instruction Buffer           │
  └─────────────────────────────────┘

15.2.3 性能特征

计算能力:

带宽利用:

内部带宽 = 16 channels × 128-bit × 2 (DDR) × 1.2GHz
        = 16 × 128 × 2 × 1.2 × 10^9 / 8
        = 614.4 GB/s (per stack)

15.3 逻辑层设计与计算单元实现

15.3.1 逻辑层物理设计

HBM-PIM的逻辑层必须在有限的面积和功耗预算内实现高效计算:

面积约束:

功耗预算:

总功耗预算 = 15W (典型HBM功耗)
PIM计算功耗 = 5W
内存访问功耗 = 8W
IO功耗 = 2W

15.3.2 计算单元设计权衡

1. SIMD宽度选择

宽度选择影响性能和面积:

性能 ∝ SIMD_width × 频率
面积 ∝ SIMD_width × log(SIMD_width)  // 考虑互联复杂度

Samsung选择16-wide SIMD的原因:

2. 数据精度支持

支持多种精度的权衡:

面积开销比例:
FP16 MAC: 1.0×
INT8 MAC: 0.3×
BF16 MAC: 0.8×
混合精度: 1.5× (支持全部)

15.3.3 内存访问模式优化

PIM架构支持三种访问模式:

1. 批处理模式(Batch Mode)

for batch in batches:
    load_weights_to_pim()      // 一次加载
    for data in batch:
        compute_in_pim(data)    // 多次复用
    store_results()

2. 流式处理模式(Streaming Mode)

while (data_available):
    fetch_next_block()          // 流水线取数
    process_in_pim()            // 并行计算
    write_back_results()        // 异步写回

3. 分块计算模式(Tiled Mode)

将大矩阵分块以适应PIM容量:
Matrix_size = M × N
Tile_size = m × n (受限于local buffer)
Tiles = ⌈M/m⌉ × ⌈N/n⌉

15.4 编程模型与软件栈

15.4.1 PIM编程抽象

1. 指令集架构(ISA)

PIM-ISA包含以下指令类型:

// 数据移动指令
PIM_LOAD  reg, mem_addr     // 从DRAM加载到寄存器
PIM_STORE mem_addr, reg     // 从寄存器存储到DRAM

// 计算指令
PIM_MAC   dst, src1, src2   // 乘累加操作
PIM_ADD   dst, src1, src2   // 向量加法
PIM_MUL   dst, src1, src2   // 向量乘法

// 控制指令
PIM_SYNC                     // 同步屏障
PIM_FENCE                    // 内存屏障

2. 编程接口

高级API示例:

// C++ API示例
class PIMTensor {
public:
    void gemm(const PIMTensor& A, const PIMTensor& B) {
        // 自动分块和调度到PIM单元
        auto tiles = partition(A, B);
        for (auto& tile : tiles) {
            schedule_to_pim(tile);
        }
        synchronize();
    }
};

15.4.2 编译器支持

PIM编译器需要解决的关键问题:

1. 计算映射

原始代码:
for i in range(M):
    for j in range(N):
        for k in range(K):
            C[i][j] += A[i][k] * B[k][j]

PIM优化后:
parallel_for pim_unit in [0..15]:
    local_M = M / 16
    for i in range(local_M):
        pim_mac(C[pim_unit][i], A[i], B)

2. 数据布局优化

优化内存布局以最大化PIM并行性:

传统行主序:A[i][j] → memory[i*N + j]
PIM优化布局:A[i][j] → memory[channel][bank][row][col]
              其中channel映射到PIM单元

15.4.3 运行时系统

1. 任务调度器

class PIMScheduler {
    queue<PIMTask> ready_queue;
    array<PIMUnit, 16> pim_units;
    
    void schedule() {
        while (!ready_queue.empty()) {
            auto task = ready_queue.front();
            auto unit = find_idle_unit();
            if (unit != nullptr) {
                dispatch(task, unit);
                ready_queue.pop();
            }
        }
    }
};

2. 内存管理

class PIMMemoryManager {
    // 维护PIM可访问内存池
    unordered_map<void*, PIMMemoryRegion> pim_regions;
    
    void* allocate_pim_memory(size_t size) {
        // 分配在PIM可访问的地址范围
        auto region = find_free_region(size);
        mark_as_pim_accessible(region);
        return region.base_addr;
    }
};

15.5 应用场景分析

15.5.1 AI推理加速

1. BERT推理优化

BERT-Base模型参数:

PIM加速关键操作:

// Attention计算
Q = Input × W_q  // 适合PIM
K = Input × W_k  // 适合PIM
V = Input × W_v  // 适合PIM
Attention = softmax(Q × K^T) × V

性能提升:
- 矩阵乘法:2.7×
- 整体推理:1.8×
- 能效比:2.2×

2. CNN推理优化

ResNet-50在ImageNet上的推理:

卷积层计算密度:
FLOPS/Byte = (K × K × C_in) / (K × K × C_in × 4 + C_out × 4)
           ≈ 0.25 (低算术强度,适合PIM)

PIM优化策略:
- 权重驻留在PIM本地
- 输入特征图流式处理
- 部分和在PIM内累加

15.5.2 图计算加速

1. PageRank算法

传统实现伪代码:
for iteration in range(max_iter):
    for v in vertices:
        rank[v] = 0.15 + 0.85 * sum(rank[u]/out_degree[u] 
                                    for u in predecessors[v])

PIM优化:
- 邻接表存储在PIM本地
- 并行更新多个顶点
- 减少随机访问开销

性能提升:3.2× (对于大规模稀疏图)

2. 图神经网络(GNN)

GCN前向传播:
H^(l+1) = σ(D^(-1/2) × A × D^(-1/2) × H^(l) × W^(l))

PIM优化点:
- 稀疏矩阵乘法
- 特征聚合操作
- 邻居采样

加速比:2.5-4.0× (取决于图稀疏度)

15.5.3 科学计算应用

稀疏矩阵求解器

SpMV操作(y = A × x):
传统实现内存访问模式:
- 不规则访问x向量
- 顺序访问A的非零元素

PIM优化:
- x向量分布存储
- 本地计算部分结果
- 减少全局归约

性能提升矩阵:
矩阵类型        加速比
带状矩阵        1.5×
随机稀疏        2.8×
幂律分布        3.5×

15.6 内存一致性挑战

15.6.1 一致性模型设计

PIM系统需要解决的一致性问题:

1. PIM与主处理器的一致性

场景:CPU和PIM同时访问相同数据
解决方案:
- 弱一致性模型 + 显式同步
- 基于区域的一致性协议
- 版本化内存管理

2. 多PIM单元间的一致性

   CPU
    │
    ├──────┬──────┬──────┐
    │      │      │      │
  PIM0   PIM1   PIM2   PIM3
    │      │      │      │
    └──────┴──────┴──────┘
         Coherence Bus

协议选择:
- 基于目录的协议(开销大)
- 基于令牌的协议(延迟高)
- 软件管理一致性(灵活性高)

15.6.2 数据一致性保证机制

1. 内存围栏(Memory Fence)

// PIM操作前后的围栏
void pim_compute_safe(void* data, size_t size) {
    memory_fence();           // 确保之前的写入完成
    pim_execute(data, size);  // PIM计算
    memory_fence();           // 确保PIM结果可见
}

2. 原子操作支持

PIM原子操作实现:
- Compare-and-Swap (CAS)
- Fetch-and-Add
- 原子归约操作

硬件支持:
- 锁定内存行
- 事务内存扩展
- 版本缓冲区

15.6.3 虚拟内存集成

地址转换挑战:

传统TLB无法支持PIM访问模式
解决方案:
1. PIM-TLB设计
   - 更大的页面(2MB/1GB)
   - 预取机制
   - 共享TLB结构

2. 段式内存管理
   - 连续物理内存分配
   - 减少转换开销

15.7 案例研究:SK Hynix AiM技术

15.7.1 AiM架构创新

SK Hynix的AiM(Accelerator in Memory)采用了不同于Samsung的设计理念:

AiM-HBM架构:
┌────────────────────────────────┐
│      GDDR6 Interface           │
├────────────────────────────────┤
│   AI Processing Unit (APU)     │
│  ┌───────────────────────────┐ │
│  │  512 RISC-V Cores        │ │
│  │  @ 1.25 GHz               │ │
│  └───────────────────────────┘ │
├────────────────────────────────┤
│      16GB HBM3 Stack           │
└────────────────────────────────┘

关键特性:
- 512个RISC-V核心
- 1.25 GHz运行频率
- 16 TFLOPS (FP16)
- 1.2 TB/s内部带宽

15.7.2 编程模型对比

AiM编程特点:

// 基于数据流的编程模型
class AiMKernel {
    void execute() {
        // 自动数据分区
        auto partitions = data_flow_partition(input);
        
        // 并行执行在512个核心上
        parallel_for(auto& p : partitions) {
            local_compute(p);
        }
        
        // 硬件加速的归约
        hardware_reduce(partitions);
    }
};

15.7.3 性能评估

基准测试结果对比:

工作负载 Samsung HBM-PIM SK Hynix AiM 传统GPU+HBM
GEMM 1.0× 1.8× 0.5×
SpMV 2.3× 2.1× 1.0×
BERT 1.8× 2.2× 1.0×
GCN 2.5× 3.1× 1.0×
功耗 35W 40W 150W

15.7.4 应用生态系统

SK Hynix AiM的软件栈:

应用层:     TensorFlow | PyTorch | ONNX
           ─────────────────────────────
框架层:     AiM Runtime API
           ─────────────────────────────
编译器:     MLIR-based Compiler
           ─────────────────────────────
驱动层:     AiM Device Driver
           ─────────────────────────────
硬件层:     AiM-HBM Hardware

15.8 未来发展趋势

15.8.1 技术演进路线

第四代PIM预期特性:

性能目标(2025-2027):

计算密度:100 TFLOPS/stack
能效比:10 TFLOPS/W
内存容量:64GB/stack
带宽:2 TB/s

15.8.2 标准化进展

JEDEC PIM标准化:

15.8.3 新兴应用领域


本章小结

近存储计算架构通过将计算能力集成到内存系统中,从根本上改变了传统的冯·诺依曼架构限制。关键要点:

  1. 架构创新:PIM/PND技术显著减少数据移动,提升能效比2-3倍
  2. 商业实现:Samsung HBM-PIM和SK Hynix AiM已实现产品化
  3. 编程挑战:需要新的编程模型、编译器和运行时支持
  4. 一致性设计:软硬件协同解决内存一致性问题
  5. 应用潜力:在AI推理、图计算等领域展现显著优势

关键公式总结:


练习题

基础题

1. PIM架构分类 描述真PIM和近数据处理(PND)的区别,并给出各自的优缺点。

提示 考虑集成位置、制造工艺、灵活性等因素
答案 真PIM将计算单元直接集成在存储阵列中: - 优点:最小化数据移动、最高带宽利用 - 缺点:受DRAM工艺限制、计算能力有限、散热困难 PND在内存控制器或基础逻辑层集成计算: - 优点:可用先进逻辑工艺、计算能力强、易于散热 - 缺点:仍有一定数据移动开销、成本较高

2. 性能计算 假设一个矩阵乘法C = A × B,其中A、B、C都是1024×1024的FP16矩阵。计算: a) 传统架构的数据移动量 b) PIM架构的数据移动量(假设权重驻留) c) 能耗节省比例(假设数据移动功耗是计算的20倍)

提示 考虑矩阵乘法的访问模式和数据复用
答案 a) 传统架构: - 读取A、B:2 × 1024² × 2 bytes = 4 MB - 写入C:1024² × 2 bytes = 2 MB - 总计:6 MB b) PIM架构(B驻留): - 读取A:1024² × 2 bytes = 2 MB - 写入C:1024² × 2 bytes = 2 MB - 总计:4 MB(节省33%) c) 能耗计算: - 传统:E_compute + 20 × E_compute × (6MB/2MB) = 61 × E_compute - PIM:E_compute + 20 × E_compute × (4MB/2MB) = 41 × E_compute - 节省:(61-41)/61 = 32.8%

3. SIMD宽度选择 解释为什么Samsung HBM-PIM选择16-wide SIMD而不是32-wide或8-wide。

提示 考虑内存行缓冲器大小、面积功耗权衡
答案 16-wide SIMD选择理由: 1. 匹配2KB行缓冲器:16 × 128 bytes = 2KB 2. 平衡计算与带宽:16 × FP16 × 1.2GHz = 38.4 GFLOPS/channel 3. 面积效率:32-wide会使面积翻倍但性能提升有限 4. 功耗约束:更宽的SIMD需要更复杂的互联和控制逻辑

挑战题

4. 一致性协议设计 设计一个简化的PIM系统一致性协议,支持CPU和多个PIM单元同时访问共享数据。要求:

提示 可以考虑基于版本或基于所有权的协议
答案 基于所有权的轻量级协议: 1. 数据分区: - 每个数据区域有唯一所有者(CPU或PIM) - 所有者可直接读写,其他需请求 2. 所有权转移: ``` Request_Ownership(addr, requester): current_owner.flush_cache(addr) transfer_ownership(addr, requester) invalidate_other_caches(addr) ``` 3. 原子操作: - 临时获取独占所有权 - 执行操作 - 释放所有权 4. 死锁避免: - 按地址顺序请求 - 超时机制 - 优先级调度

5. 编译器优化 给定以下代码,展示如何将其优化以在PIM上高效执行:

# 稀疏矩阵向量乘法
for i in range(n):
    for j in row_ptr[i]:row_ptr[i+1]:
        y[i] += val[j] * x[col_idx[j]]
提示 考虑数据布局、并行化策略、预取
答案 PIM优化版本: ```python # 1. 数据布局优化 # 将x向量复制到各PIM单元本地 # 2. 工作负载均衡分配 rows_per_pim = balance_rows_by_nnz(row_ptr, num_pim_units) # 3. PIM并行执行 parallel_for pim_id in range(num_pim_units): local_rows = rows_per_pim[pim_id] # 预取x向量元素 prefetch_x_elements(local_rows, col_idx) # 本地计算 for i in local_rows: local_sum = 0 for j in row_ptr[i]:row_ptr[i+1]: local_sum += val[j] * x_local[col_idx[j]] y_local[i] = local_sum # 结果写回 writeback_y_results(y_local) ``` 关键优化: - 按非零元素数量均衡负载 - x向量元素本地缓存 - 消除随机访问 - 批量写回结果

6. 应用场景分析 分析以下哪些应用最适合PIM加速,并说明原因: a) 密集矩阵LU分解 b) 图的广度优先搜索 c) 快速傅里叶变换 d) K-means聚类

提示 考虑计算密度、访问模式、数据复用率
答案 适合程度排序:b > d > a > c b) BFS - 最适合: - 不规则内存访问模式 - 低计算密度(访存受限) - PIM可大幅减少随机访问开销 d) K-means - 适合: - 距离计算的数据并行性高 - 中等计算密度 - 适合SIMD加速 a) LU分解 - 中等: - 需要复杂的数据依赖管理 - 部分操作(GEMM)适合PIM - 关键路径上的串行依赖限制并行性 c) FFT - 最不适合: - 复杂的蝶形运算模式 - 高数据复用率(cache友好) - 位反转访问模式难以优化

7. 性能建模 建立一个PIM系统的性能模型,考虑:

提示 使用Amdahl定律的扩展形式
答案 PIM性能模型: ``` T_total = T_host + T_pim + T_sync 其中: T_host = (1-f) × T_original T_pim = f × T_original / (S_compute × U_bandwidth) T_sync = N_sync × L_sync 加速比: Speedup = T_original / T_total = 1 / ((1-f) + f/(S×U) + N_sync×L_sync/T_original) 关键参数: f: 可并行化比例 S: PIM计算加速比 U: 带宽利用率 N_sync: 同步次数 L_sync: 同步延迟 ``` 影响因素分析: 1. f越大,潜在加速越高 2. U受访问模式影响(随机访问U低) 3. N_sync×L_sync需要最小化 4. S受PIM计算能力限制 临界点分析: 当 f/(S×U) + N_sync×L_sync/T_original > f 时,PIM反而变慢

8. 未来架构设想 设计一个理想的下一代PIM架构,包括:

提示 考虑可重构性、异构计算、新型存储器
答案 下一代PIM架构设想: 1. **异构计算单元**: - RISC-V通用核心(控制流) - 可重构数据流引擎(规则计算) - 专用加速器(AI、加密) 2. **分层内存组织**: ``` L1: SRAM缓存 (每个PIM单元) L2: 3D堆叠DRAM (高带宽) L3: 新型NVM (大容量持久化) ``` 3. **可编程互联**: - 片上网络(NoC)连接PIM单元 - 动态可重构拓扑 - 支持广播、归约等集合通信 4. **统一编程模型**: ```cpp @pim_kernel def compute(data): # 自动分区和映射 with pim.parallel(): result = pim.map_reduce( mapper=custom_op, reducer=sum, data=data ) return result ``` 实现挑战: - 工艺集成:逻辑与存储工艺不兼容 - 热管理:3D堆叠的散热问题 - 软件复杂性:需要全新的编译器和运行时 - 标准化:缺乏工业标准 - 成本:研发和制造成本高

常见陷阱与错误

设计陷阱

  1. 过度优化计算能力
    • 错误:追求高FLOPS而忽视内存带宽匹配
    • 正确:平衡计算与访存能力
  2. 忽视热设计
    • 错误:在有限空间堆叠过多计算单元
    • 正确:考虑功耗密度和散热路径
  3. 一致性过度设计
    • 错误:实现复杂的硬件一致性协议
    • 正确:采用软件管理的轻量级协议

编程陷阱

  1. 不当的数据布局
    • 错误:沿用传统的行/列主序
    • 正确:按PIM单元分区的布局
  2. 频繁同步
    • 错误:细粒度同步导致开销过大
    • 正确:批量操作减少同步次数
  3. 忽视负载均衡
    • 错误:简单的静态分区
    • 正确:基于工作量的动态均衡

性能陷阱

  1. 错误的性能预期
    • 错误:期望所有应用都能加速
    • 正确:识别适合PIM的应用特征
  2. 忽视数据传输开销
    • 错误:只考虑计算时间
    • 正确:包含初始化和结果回传时间

最佳实践检查清单

架构设计审查

软件栈评估

应用适配性分析

性能优化要点

部署就绪检查