两个瓶颈共用一条通信路径
论文把基于 GPU 的优化描述为面临两个不同的扩展极限,而它们共用同一条通信路径。在问题规模较小时,模型能放进 GPU 内存,但反复的主机协调会限制服务能完成多少并发决策。在问题规模较大时,稠密耦合矩阵需要 O(n²) 存储,而 B 个求解器副本的 O(Bn) 状态可以常驻,因此扩展瓶颈从请求速率变成系数投递。
所提出的架构通过 NVIDIA DOCA GPUNetIO 同时应对这两点,该接口把接收和发送操作暴露给 CUDA 内核。对于常驻模型,一个持久服务接收场更新,在单个 GPU 线程块内执行每次求解,并返回结果。精确整数耦合求和、GPU 工作队列和批量传输让接收—求解—回复路径留在设备上,无需专用 CPU 数据通路核心。对于大于设备内存的模型,流式求解器把动力学状态保留在 GPU 上,并在各副本间复用到达的耦合分块。
这一区分很重要,因为两种模式压的是不同资源。常驻模式看的是大量并发短求解下的调度开销;流式模式看的是求解器状态不动时的持续带宽。论文分别评估两者,而不是给出一个混合数字。
每块一个请求让求解彼此独立
每个请求由一个 256 线程的线程块求解。把 n 补齐到 32 的倍数后,B·n_p 个(副本,行)对按循环方式分配到各线程,每个线程在整个轨迹中把至多 16 个对的位置和动量保存在寄存器里,因此 B·n_p ≤ 4096。由于 n_p 和线程数都是 32 的倍数,一个 warp 的 32 个 lane 总是持有同一副本的 32 个连续行,因此一个 warp 的新符号通过 __ballot_sync 恰好构成该副本符号向量的一个 32 位字,无需原子操作或 shuffle。
服务器为所有 worker 固定一个共享内存占用 S,这决定了每个流多处理器上能驻留多少块,从而决定同时有多少请求在服务中。当 S = 48 KiB 时,服务器 GPU 的 188 个 SM 上各能放两个块,共 376 个并发请求。另有四个块槽位留给驱动工作。
论文报告,在最初版本中每个自旋块每次迭代都读取关闭标志;372 个块在紧循环中发出 PCIe 读,耗尽了网卡自身的 DMA 和 doorbell,把往返时间推高到毫秒级。现在每个块最多每 0.5 ms 轮询一次该标志,从而减少 PCIe 流量。这是主机监控与 GPU 占用率如何影响延迟的一个具体例子。
精确整数求和让 GPU 与 CPU 轨迹一致
求解器的耦合求和是精确计算的,而非近似。对于以位平面存储的 ±1 耦合,对 j 求和的 J_ij·s_j 等于 n − 2·popcount(u_i ⊕ v) + s_i。对于 {−1, 0, 1} 中的三元耦合,该和等于 2·(popcount(P_i ∧ v) − popcount(M_i ∧ v)) − (|P_i| − |M_i|)。对于 |J_ij| ≤ 127、|h_i| < 2^15 且 n ≤ 2048 的 int8 耦合,int32 DP4A 求和是精确的,且 |a_i| < 2^24,因此在 FP32 中也是精确的。
论文由此得出的结论是:如果其余算术以相同的 IEEE 就近舍入操作、按相同顺序求值,GPU 和 CPU 参考实现会产生完全相同的轨迹、自旋和能量。GPU 更新使用显式舍入的乘法、加法和减法(__fmul_rn、__fadd_rn、__fsub_rn)以防止融合乘加收缩,主机参考实现则以 -ffp-contract=off 编译。
这对比较实现的读者很重要:论文的主张不是 GPU 结果接近参考,而是耦合求和在两侧是同一个整数,且其余每个操作都是对相同操作数的正确舍入 IEEE 操作。精确性界限是针对 n ≤ 2048 陈述的,这是范围条件而非普遍保证。
延迟优势出现在并发负载下
核心比较对象是使用同一求解器的基于 socket 的服务器。在每秒 80 万请求的提供负载下,GPUNetIO 完成 618–628 kreq/s,调优代理完成 620–668 kreq/s,均无丢失,此时客户端限制了注入速率。GPUNetIO 的中位往返时间此时为 189 µs,而调优代理为 288 µs;其第 99 百分位往返时间为 218 µs,而调优代理为 609 µs——分别降低到 1/1.5 和 1/2.8。在 600 kreq/s 时对应值为 188 对 240 µs 和 216 对 327 µs;在 400 kreq/s 时两者仍接近,为 178 对 193 µs 和 207 对 229 µs。
扩展行为是更具决策相关性的数字。在提供负载从 400 到 800 kreq/s 之间,GPUNetIO 的中位往返时间上升 6%,而代理上升 50%。服务器端时间戳有助于解释这一点:在同一区间内,GPUNetIO 的中位服务器驻留时间保持在 156–159 µs,第 99 百分位保持在 180–186 µs,而代理则从 173 升至 235 µs、从 208 升至 317 µs。
论文明确指出,空载延迟与调优代理接近。无负载时,主要收益是释放出的服务器 CPU 核心和对主机敏感性的降低;更大的延迟差异出现在并发负载下。每个 CPU 中介基线都专门用一个轮询核心接收请求并返回结果,而 GPUNetIO 在设置完成后在设备上完成这项工作。
批量回复避开发送侧瓶颈
论文报告了一个批量传输旨在避免的失效模式。在最高提供负载下,逐回复发送仅完成 334 kreq/s,中位往返时间为 24 ms,请求丢失 41%。批量描述符投递在测试速率下避开了这一瓶颈,使回复提交不再限制请求服务。
这一比较还有一个论文直接陈述的边界。launch 服务器更早达到其四流上限,约为 24 kreq/s,因此在最高测试负载下 launch 路径不是相关基线。在客户端饱和的两个最高速率下,两个服务器的个别运行偶尔出现毫秒级第 99 百分位;在 700 kreq/s 时,这使 GPUNetIO 的中位第 99 百分位(423.5 µs)略高于代理(381 µs)。
在闭环网格的 19 个设置中,GPU 发起的服务在其中 15 个设置上录得最低中位数,比更快的调优基线改善 1.5–9.2 µs;其余四个设置以 1.5–2.5 µs 之差有利于某个基线。其录得的服务器驻留时间在整个网格中都更低。论文指出,残差使用不同的时间戳边界,因此它分别报告驻留时间和往返时间的其余部分。
流式以内存换带宽
对于大于设备内存的模型,流式求解器逐块接收耦合矩阵,而位置、动量、符号和行累加器留在接收 GPU 上。稠密一位表示的逻辑大小为 n²/8 字节。帧携带 64 字节头部(含以太网)和 4032 字节载荷,表示一行的 32,256 个耦合,最后一个列块会被填充。
对于 n = 10^7,逻辑矩阵为 12.5 TB,而一趟传输在 3.11×10^9 帧中携带 12.53952 TB。接收端有一个含 16,384 个 4096 字节槽位的循环队列,并向 372 个各 512 线程的持久 worker 块发布突发。在 n = 10^7 且 B = 8 时,行累加器需要 320 MB。论文报告,12.5 TB 的逻辑矩阵通过 64 MiB 数据包缓冲区被消费。
在执行耦合累加时测得的速率约为 307 Gb/s。一个 4096 字节帧含 FCS、前导码和包间隙共占 4120 字节,在 400 GbE 链路上给出 391.46 Gb/s 的理想载荷上限,因此观测速率达到该上限的约 78%。论文把差距归因于当前 PCIe 5.0 服务器的 GPU 到网卡路径要经过主机互连,并指出直连 PCIe 交换路径、足够的上行带宽和均衡的队列放置是缩小差距的候选方案。
验证依赖植入实例与参考运行
验证结合了流记账、植入解检查和参考执行。接收端把解析出的流帧总数与结束标记比较,并记录丢弃的突发。Mattis 实例提供精确基态值 2E = −n(n−1),用于检查累加能量和求解器积分。在 n = 10^5 时,Mattis 和随机的能量与校验和记录与常驻 GPU 参考逐字节一致;在 n = 10^4 时,随机记录也与 CPU 参考一致。这些记录包含每个记录步骤的最佳副本能量和 64 位自旋位图校验和。
流式运行使用种子 42、Δt = 1.1 和 ξ = 0.5/√n。n = 10^7、B = 1 的运行使用两次更新;其 B = 8 的运行使用十次。n = 10^4 和 10^5 的参考比较使用 20 次更新。一次 K 次更新的运行需要 K + 1 趟矩阵传输,最后一趟只评估最终能量而不推进状态。
报告的接收趟区间在主机观察到结束标记时结束,主机每 2 ms 轮询一次。完整迭代时间还包括排空未完成工作、更新状态和确认该趟,这些控制操作使用主机轮询。论文指出,所评估的实现对其接收和控制计数器使用映射主机内存,并且在测得速率下循环数据包缓冲区约容纳 1.7 ms 的到达帧。
两种模式尚未覆盖的范围
请求评估使用一个平台和两个基于 socket 的基线。论文指出,使用相同求解器、数据包格式和批量策略的匹配 DPDK/GPUdev 基线是有用的下一步比较,以把 GPU 发起的收益与内核旁路的收益分开。这是对延迟比较的范围条件:所测优势是相对于基于 socket 的服务器,而非相对于批量策略匹配的内核旁路基线。
当前请求边界仍为每次求解一帧、一个 512 KiB 模型槽位,以及映射中描述的寄存器和共享内存限制。论文指出的部署扩展包括同步替换使用中的模型、重传和逐帧序列验证,以及把流式工作分布到多个接收端。
在流式方面,论文指出测得的 306–307 Gb/s 对应约 38.3 GB/s 的系数载荷,而三星 9100 PRO PCIe 5.0 NVMe SSD 标称顺序读取最高 14.8 GB/s,因此用这类存储供给所测流需要并行多块盘。系数源必须持续提供这一带宽才能连续供给接收端。论文还观察到,一个和八个副本的速率相近,说明在保留副本复用的同时还有提高投递带宽的空间。
两种模式在实践中的分野
论文自身的划分是请求速率扩展与模型规模扩展,两者产生不同的决策阈值。如果模型能放进 GPU 内存且工作负载是大量并发短求解,相关比较是 400 到 800 kreq/s 区间,其中 GPUNetIO 的中位往返时间上升 6%,而调优代理上升 50%,且在 800 kreq/s 时第 99 百分位为 218 µs 对 609 µs。优势并不在空载延迟上。
如果模型超过设备内存,相关数字是持续系数投递速率:约 307 Gb/s,对照 400 GbE 链路上 391.46 Gb/s 的载荷上限,且 K 次更新中的每一次都需要再一趟矩阵传输和一趟仅评估最终能量的传输。在同一链路的理想载荷上限下,n = 10^7 配置的传输项将约为 256 s,而非当前每接收趟约 327 s;在相同帧效率下,800 GbE 链路会把理想项降到约 128 s。
因此最有用的解读是有条件的,而非单一结论。GPU 发起路径在主机协调原本会随到达速率和队列数增长的地方收益最大,而流式路径在二次系数无法保留但求解器状态可以保留的地方收益最大。论文自身的框架——两种模式对同一条通信路径提出不同要求——是值得带走的区分。
本文引用的文献
GPU-Initiated Discrete Simulated Bifurcation: Low-Latency Requests and Streaming Dense Couplings
基于 NVIDIA DOCA GPUNetIO 构建的离散模拟分岔服务把接收—求解—回复路径留在 GPU 上,在每秒 80 万请求的提供负载下把中位往返延迟保持在 189 µs、第 99 百分位延迟保持在 218 µs,并且流式求解器通过 64 MiB 数据包缓冲区以约 307 Gb/s 消费 12.5 TB 的逻辑稠密矩阵。
