Files
Inbox/系统基座文件/2/2.2/2.2.2 异步流水线与计算通信重叠 (Asynchronous Pipelining & Compute-Copy Overlap).md
2025-12-11 07:24:36 +08:00

5.6 KiB
Raw Blame History

tags, date created, date modified
tags date created date modified
星期四, 十一月 20日 2025, 9:50:03 晚上 星期四, 十一月 20日 2025, 9:50:24 晚上

2.2.2 异步流水线与计算通信重叠 (Asynchronous Pipelining & Compute-Copy Overlap)

覆盖范围:定义如何利用智铠 GPU 的独立 Copy Engine (DMA 引擎) 与 Compute Engine (计算引擎) 的并行能力,通过 CUDA Streams 实现“传输 - 计算 - 传输”的三级流水线并行,从而掩盖 PCIe 总线的物理延迟。

一、 约束输入与对齐

  1. 硬件能力Iluvatar MR-V100 通常具备独立的 Copy Engine用于 H2D/D2H和 Compute Engine。这意味着 数据拷贝Kernel 执行 在硬件上是物理隔离的,可以同时进行。
  2. API 约束:必须使用 Async 系列 API (如 cudaMemcpyAsync) 配合 Non-Default Stream 才能触发重叠。
  3. 业务逻辑:雷达信号处理通常是流式的:接收(H2D) -> 处理(Kernel) -> 输出(D2H)

二、 权衡分析与选项呈现 (Trade-off Matrix)

我们主要在流的设计模式上进行权衡:

选项 A. 单流串行 (Serial Stream) B. 多流乒乓/多缓冲 (Multi-Stream Ping-Pong) (推荐) C. 细粒度多流 (Hyper-Q)
机制 1 个流。H2D -> Kernel -> D2H 顺序执行。 2-3 个流。Stream A 做计算时Stream B 做 H2D 拷贝。 N 个流N >> 3。将任务切分为极小片。
PCIe 利用率 。总线在 Kernel 计算期间闲置。 。总线和计算单元始终处于忙碌状态。 极高,但调度开销大。
延迟掩盖 无掩盖。总耗时 = T(copy) + T(compute)。 完全掩盖。理想情况下总耗时 = max(T(copy), T(compute))。 同上,但可能引入调度抖动。
实现复杂度 低。 中。需要管理多个 Buffer 的状态 (Ping-Pong)。 高。
适用性 调试模式。 雷达实时处理标准范式。 超大规模并发任务。

三、 基线确立与实施规范

为了最大化吞吐量,我们确立 B. 多流乒乓 (Multi-Stream Ping-Pong) 为设计基线。

1. 流水线架构基线:三级流水线 + 双流 (Double Buffering)
  • 核心逻辑:创建 2 个 CUDA Stream (Stream 0, Stream 1) 和 2 组页锁定内存 Buffer (Buffer A, Buffer B)。
  • 调度策略
    • 时刻 T0Stream 0 开始传输 Buffer A (H2D)。
    • 时刻 T1
      • Stream 0 开始处理 Buffer A (Kernel)。
      • 同时Stream 1 开始传输 Buffer B (H2D) —— 此处发生了 Copy 与 Compute 的重叠
    • 时刻 T2
      • Stream 0 开始回传 Buffer A 结果 (D2H)。
      • Stream 1 开始处理 Buffer B (Kernel)。
2. 关键 API 实施规范
  • 流创建

    cudaStream_t streams[2];
    for(int i=0; i<2; i++) cudaStreamCreateWithFlags(&streams[i], cudaStreamNonBlocking);
    
    • 注意:必须使用 cudaStreamNonBlocking防止与默认流Default Stream发生隐式同步导致流水线断流。
  • 异步传输

    // 必须使用 Async 版本,且指定 stream
    cudaMemcpyAsync(d_ptr, h_ptr, size, cudaMemcpyHostToDevice, streams[i]);
    
  • 同步策略

    • 严禁使用 cudaDeviceSynchronize()(全卡同步)。
    • 推荐使用 cudaStreamSynchronize(streams[i])cudaEventRecord/Synchronize 来精细控制单个 Buffer 的生命周期,确保 Host 端在复用 Buffer 前GPU 已经操作完毕。
3. 缓冲区管理状态机

为了配合 01_数据接收模块MemoryPool,我们需要一个简单的状态机来管理 Buffer 在 Host 和 Device 之间的流转:

  • HOST_OWNED (I/O 线程填充数据)
  • DEVICE_OWNED_H2D (正在上传)
  • DEVICE_OWNED_COMPUTE (正在计算)
  • DEVICE_OWNED_D2H (正在回传)
  • RELEASED (回传完毕,归还 Pool)
stateDiagram-v2
    %% 状态定义
    state "HOST_OWNED<br/>(主机所有)" as HOST
    state "DEVICE_OWNED_H2D<br/>(传输中: H->D)" as H2D
    state "DEVICE_OWNED_COMPUTE<br/>(计算中: Kernel)" as COMPUTE
    state "DEVICE_OWNED_D2H<br/>(传输中: D->H)" as D2H
    state "RELEASED<br/>(待归还)" as RELEASED

    %% 流程流转
    [*] --> HOST : 从 MemoryPool 申请

    HOST --> H2D : I/O线程填充数据\n并调用 cudaMemcpyAsync
    note right of HOST
        此时数据位于页锁定内存
        CPU 写入完成
    end note

    H2D --> COMPUTE : 记录 H2D_Event\nStreamWaitEvent
    note right of H2D
        DMA 引擎正在搬运
        CPU 不阻塞
    end note

    COMPUTE --> D2H : Kernel 执行完毕\n自动触发 D2H
    note right of COMPUTE
        GPU 核心正在计算
        数据驻留显存
    end note

    D2H --> RELEASED : D2H 完成回调\n或 Event 同步
    note right of D2H
        结果已写回 Host
    end note

    RELEASED --> HOST : DataPacket 析构\n自动归还 Pool
    
    RELEASED --> [*]

下一步行动

我们已经定义了 “怎么传”Pinned Memory“怎么调度”Async Streams。 接下来,我们需要解决 “传给谁 的问题,即 2.2.3 NUMA 感知的内存亲和性控制。考虑到飞腾 S5000C 的双路架构,如果数据传错了 CPU 节点,上述所有优化都会因为 QPI 总线瓶颈而大打折扣。

提问:您是否同意将 “双流乒乓 (Double Stream Ping-Pong)” 作为异步流水线的基线?确认后我们进入 2.2.3 NUMA 亲和性的讨论。