【GPU 微架构技术】Pending Request Table(PRT)技术详解
PRT(Pending Request Table)是 GPU 中用于管理 未完成内存请求(outstanding memory requests)的一种硬件结构,旨在高效处理大规模并行线程的内存访问需求。与传统的 MSHR(Miss Status Handling Registers)不同,PRT 的设计更适应 GPU 的 warp 级并行性,显著提升了内存子系统的吞吐量和并发能力。以下从工作原理、优势、与 MSHR 的对比等方面详细解析 PRT 技术。
1. PRT 的核心设计思想
PRT 的核心是为 每个 warp 的内存指令(如加载或存储)分配一个独立的条目,而非为每个内存请求分配资源。这一设计充分利用了 GPU 的 warp 执行模型(32 个线程以 SIMD 方式并行执行),通过合并一个 warp 内所有线程的内存请求,减少对硬件资源的占用。
- 条目内容:
每个 PRT 条目包含以下信息:- 内存指令的 目标地址块(如全局内存地址)。
- 线程掩码(标识哪些线程需要该数据)。
- 地址偏移(记录每个线程在目标地址块内的偏移量)。
- 未完成请求计数器(跟踪该指令关联的内存请求数量)。
2. PRT 的工作流程
-
内存指令执行:
当 warp 执行一条内存指令(如LDG
加载指令)时,GPU 的 Load/Store 单元会 合并线程的访问请求。例如,若多个线程访问同一缓存行,则合并为一个内存请求。 -
PRT 条目分配:
- 若发生缓存未命中(数据不在 L1/L2 缓存中),分配一个 PRT 条目。
- 每个 PRT 条目对应一个 warp 的内存指令,而非单个线程或单个地址请求。
-
生成内存请求:
- 合并后的请求被发送到显存(DRAM)或 L2 缓存。
- 每个请求包含:
- 目标地址块(如 128 字节的缓存行地址)。
- PRT 条目标识符(用于后续数据分发)。
- 线程掩码(标记哪些线程需要该数据)。
-
数据返回与分发:
- 当显存返回数据时,根据 PRT 条目中的 地址偏移,将数据分发到各线程的寄存器。
- 例如,若线程 0 需要地址块内偏移 4 字节的数据,则从返回的缓存行中提取对应位置的数据。
-
释放 PRT 条目:
- 当所有关联的内存请求完成,且数据分发完毕后,释放 PRT 条目。
3. PRT 的关键优势
-
高并发处理能力
PRT 的未完成请求数 仅受限于每个 SM 的 PRT 条目数量,而非线程数或未合并访问数。例如,在 Kepler 架构中,每个 SM 有 44 个 PRT 条目,每个条目可处理一个 warp 的 32 个线程请求,理论最大并发请求数为:
[
44 , \text{条目} \times 32 , \text{线程/warp} = 1408 , \text{未完成请求}
]
相比 Fermi 的 MSHR(128 请求/SM),并发能力提升 11 倍。 -
对未合并访问的容忍性
MSHR 在未合并访问(如随机内存访问)时,需要为每个未合并请求分配独立条目,容易导致资源耗尽。而 PRT 的条目与 warp 指令 绑定,无论线程访问是否合并,每个指令仅占用一个 PRT 条目。这使得 PRT 在 非连续内存访问场景 下表现更优。 -
简化硬件资源管理
PRT 通过合并 warp 级请求,减少了对细粒度资源(如每个线程的请求跟踪)的需求,降低了硬件复杂度。
4. PRT 与 MSHR 的对比
特性 | MSHR | PRT |
---|---|---|
设计目标 | 跟踪每个缓存行未命中请求 | 跟踪每个 warp 的内存指令 |
条目分配粒度 | 每个缓存行一个条目 | 每个 warp 内存指令一个条目 |
合并能力 | 有限(如 8 个线程合并) | 天然支持整个 warp(32 线程)合并 |
未完成请求上限 | 受限于条目数(如 Fermi 的 128) | 受限于条目数 × warp 线程数(如 1408) |
适用场景 | 连续内存访问(高合并率) | 任意内存访问模式(包括随机访问) |
5. PRT 的实际应用与优化启示
-
对开发者的意义
- Kepler 及后续架构:开发者无需过度优化内存合并,可更灵活设计内存访问模式。
- 控制 warp 指令并发数:避免单个 SM 内过多 warp 同时发起内存指令,以防 PRT 条目耗尽。
-
对架构设计的启示
- 扩展 PRT 条目数:增加 PRT 条目可进一步提升并发能力(如 NVIDIA 后续架构的改进)。
- 结合缓存优化:PRT 与 L1/L2 缓存协同工作,需平衡缓存命中率与显存带宽利用率。
6. 论文中的实验验证
论文通过 Thread-Latency 图 验证了 PRT 的优势:
- Kepler(Tesla K20):当每个线程发起 2-3 次内存请求时,PRT 条目饱和点对应于 44 个 warp 指令(图 9-10),而非线程数或请求数,表明其设计基于 warp 级管理。
- 对比 Fermi:Fermi 的 MSHR 在未合并访问时快速饱和(图 3-4),而 Kepler 的 PRT 在相同场景下表现更优。
参考资料
- https://slideplayer.com/slide/8276701/
- https://www.ahmado.com/profile/lashgar/files/16acmcan.pdf