FIFO Pipeline 深度对比分析:博客理论 ↔ DeepEP 源码 ↔ DeepGEMM Mega MoE 源码

分析目标:探究博客"FIFO: From Synchronous to Streaming Pipeline"概念在 DeepEP 和 DeepGEMM 两个代码库中的实际同步机制实现。

核心问题:
1. DeepEP 是否使用了 FIFO?其同步原语是什么?
2. DeepGEMM Mega MoE 的同步机制是什么?
3. 两者的同步模式有何本质差异?
4. FIFO 概念如何与 Warp Spec、Chunk Streaming、Normal vs Low-Latency 关联?


1. TL;DR

问题 结论
DeepEP 是否使用 FIFO? 否——使用 NCCL Barrier + mbarrier 的同步模式,无显式 FIFO 队列
DeepGEMM 是否使用 FIFO? 是,但形式不同——使用 mbarrier + double-buffering 实现等效 FIFO 语义
两者同步原语差异? DeepEP: this_grid().sync() + NCCL signal/wait;DeepGEMM: atomic_add_rel + ld_acq 自旋
FIFO 本质? 两者都实现了流式执行,但同步机制完全不同
博客理论是否准确? 部分准确——博客描述的 FIFO 模型更贴近 DeepGEMM 的实现,而非 DeepEP

2. 博客核心概念回顾:FIFO 的流式本质

博客 Section 6 描述了 FIFO 的核心思想:

2.1 博客原文描述

无 FIFO(同步):
Send → Barrier → Forward → Barrier → Receive
      ↑ 必须等前一阶段全部完成

有 FIFO(流式):
Send → FIFO → Forward → FIFO → Receive
      ↑ 每个阶段只关心自己的读写,无需等待整个 Batch

FIFO 的本质:将通信 pipeline 从同步执行转变为流式执行(streaming execution)。

2.2 博客的关键断言

博客断言 含义
"无需等待整个 Batch" Chunk 粒度流式处理
"每个阶段只关心自己的读写" Stage 解耦
"FIFO 队列" 显式或隐式的生产者-消费者缓冲
"同步→流式" Barrier → FIFO 的转变

3. DeepEP 实现分析:NCCL-Based 同步模式

3.1 DeepEP 的同步原语全景

DeepEP 没有使用显式 FIFO 队列,而是采用 NCCL Barrier + mbarrier 的混合同步模式:

graph TB
    subgraph "DeepEP 同步原语"
        direction TB

        subgraph "全局同步 (NCCL)"
            A1["gpu_barrier<br/>this_grid().sync()<br/>+ NCCL signal/wait"]
            A2["nvlink_barrier_wo_local_sync<br/>red_add_rel_sys<br/>+ ld_acq_sys 自旋"]
        end

        subgraph "数据流同步 (mbarrier)"
            B1["mbarrier_arrive_and_set_tx<br/>TMA load 完成信号"]
            B2["mbarrier_wait_and_flip_phase<br/>Consumer 等待"]
            B3["cp_async_mbarrier_arrive<br/>cp.async 完成信号"]
        end

        subgraph "Warp 内同步"
            C1["named_barrier<br/>bar.sync"]
            C2["__syncwarp()<br/>Warp 内线程同步"]
        end

        subgraph "原子操作"
            D1["atomicAdd_block<br/>SM 内共享内存计数"]
            D2["atomicAdd<br/>全局内存计数"]
        end
    end

3.2 gpu_barrier:DeepEP 的核心同步机制

DeepEP 的 gpu_barrier 是整个同步体系的基石:

// deep_ep/include/deep_ep/common/comm.cuh
template <bool kIsScaleupNVLink, int kNumScaleoutRanks, int kNumScaleupRanks,
          int kNumSMs, int kNumThreads, int kNumQPs,
          int64_t kNumTimeoutCycles, int kTag = kDeviceBarrierTag,
          bool kFlushStores = true, bool kSyncAtStart = true, bool kSyncAtEnd = true>
__forceinline__ __device__ void gpu_barrier(const handle::NCCLGin& gin,
                                            const layout::WorkspaceLayout& workspace,
                                            const int& scaleout_rank_idx, const int& scaleup_rank_idx,
                                            const int& sm_idx, const int& thread_idx,
                                            bool do_scaleout = true, bool do_scaleup = true) {
    // 1. TMA store 刷新(确保数据全局可见)
    if constexpr (kFlushStores) {
        ptx::tma_store_commit();
        ptx::tma_store_wait();
        __syncwarp();
    }

    // 2. 所有 SM 到达同步点
    if constexpr (kSyncAtStart) {
        cooperative_groups::this_grid().sync();  // ← 全局 SM 同步
    }

    // 3. 跨 rank 同步(scaleup/scaleout)
    if (do_scaleup and do_scaleout) {
        if (sm_idx == 0) {
            scaleup_barrier_wo_local_sync<...>(...);  // NVLink barrier
        } else {
            scaleout_barrier_wo_local_sync<...>(...);  // RDMA barrier
        }
    }

    // 4. 所有 SM 再次同步
    if constexpr (kSyncAtEnd)
        cooperative_groups::this_grid().sync();  // ← 全局 SM 同步
}

关键特征:
- 使用 cooperative_groups::this_grid().sync() 实现 SM 间同步
- 跨 rank 同步使用 NCCL 的 signal/wait 机制
- 这是一个全局 Barrier,不是 FIFO!

3.3 mbarrier:DeepEP 的数据流同步

DeepEP 使用 mbarrier 实现 TMA load/store 的 producer-consumer 协议:

// deep_ep/include/deep_ep/common/ptx.cuh

// mbarrier 初始化
__forceinline__ __device__ void mbarrier_init_with_fence(mbarrier* ptr, const int& arrive_count = 1) {
    asm volatile("mbarrier.init.shared::cta.b64 [%1], %0;" ::
                 "r"(arrive_count), "r"(static_cast<uint32_t>(__cvta_generic_to_shared(ptr))));
    asm volatile("fence.mbarrier_init.release.cluster;" ::);
}

// arrive + expect_tx(生产者:数据加载完成)
__forceinline__ __device__ void mbarrier_arrive_and_set_tx(mbarrier* ptr, const int& num_bytes) {
    asm volatile("mbarrier.arrive.expect_tx.shared::cta.b64 _, [%1], %0; \n\t" ::
                 "r"(num_bytes), "r"(static_cast<uint32_t>(__cvta_generic_to_shared(ptr))));
}

// wait + phase flip(消费者:等待数据就绪)
__forceinline__ __device__ void mbarrier_wait_and_flip_phase(mbarrier* ptr, arrival_phase& phase) {
    asm volatile(
        "{\n\t"
        ".reg .pred       P1; \n\t"
        "LAB_WAIT: \n\t"
        "mbarrier.try_wait.parity.shared::cta.b64 P1, [%0], %1, %2; \n\t"
        "@P1 bra DONE; \n\t"
        "bra     LAB_WAIT; \n\t"
        "DONE: \n\t"
        "}" ::
        "r"(static_cast<uint32_t>(__cvta_generic_to_shared(ptr))),
        "r"(phase), "r"(0x989680));
    phase ^= 1;
}

3.4 Dispatch 中的同步模式

// deep_ep/include/deep_ep/impls/dispatch.cuh

// 1. 初始 barrier:确保所有 rank 就绪
comm::gpu_barrier<kIsScaleupNVLink, 1, kNumRanks,
                  kNumSMs, kNumThreads, kNumQPs, kNumTimeoutCycles, comm::kDispatchTag0, false, false, true>(
    gin, workspace_layout, 0, rank_idx, sm_idx, thread_idx);

// 2. 主循环:per-token 处理
for (int token_idx = token_start; token_idx < num_tokens; token_idx += token_stride) {
    // TMA load token 数据
    ptx::tma_load_1d(tma_buffer.get_hidden_ptr(), ..., mbarrier_ptr, kNumHiddenBytes);

    // 等待 TMA load 完成
    ptx::mbarrier_arrive_and_set_tx(mbarrier_ptr, kNumHiddenBytes);
    ptx::mbarrier_wait_and_flip_phase(mbarrier_ptr, phase);

    // TMA store 到远程/本地
    ptx::tma_store_1d(dst_ptr, tma_buffer.get_base_ptr(), ...);
    ptx::tma_store_commit();
}

// 3. 最终 barrier:确保所有数据到达
comm::gpu_barrier<kIsScaleupNVLink, 1, kNumRanks,
                  kNumSMs, kNumThreads, kNumQPs, kNumTimeoutCycles, comm::kDispatchTag1, true, true, false>(
    gin, workspace_layout, 0, rank_idx, sm_idx, thread_idx);

3.5 DeepEP 的同步模式总结

同步原语 用途 粒度
gpu_barrier 全局 SM + 跨 rank 同步 所有 SM
mbarrier TMA load/store producer-consumer per-warp
named_barrier Warp group 内同步 Warp group
__syncwarp Warp 内线程同步 Warp
atomicAdd 元数据计数 全局/共享内存

关键结论:DeepEP 使用 Barrier 主导 的同步模式,mbarrier 仅用于 TMA 内部的数据就绪检测,不构成 FIFO 队列。


4. DeepGEMM Mega MoE 实现分析:mbarrier-Based 流式模式

4.1 DeepGEMM 的同步原语全景

DeepGEMM 使用 mbarrier + double-buffering 实现等效 FIFO 语义:

graph TB
    subgraph "DeepGEMM 同步原语"
        direction TB

        subgraph "全局同步 (barrier.cuh)"
            A1["grid_sync<br/>atomic_add_rel + ld_acq 自旋"]
            A2["nvlink_barrier<br/>red_add_rel_sys + ld_acq_sys 自旋"]
        end

        subgraph "数据流 FIFO (mbarrier)"
            B1["full_barriers[]<br/>TMA load 完成信号<br/>arrive_and_expect_tx / wait"]
            B2["empty_barriers[]<br/>Consumer 释放信号<br/>arrive / wait"]
            B3["tmem_full_barriers[]<br/>TMEM 累积完成"]
            B4["tmem_empty_barriers[]<br/>TMEM 可重用"]
            B5["combine_barriers[]<br/>Combine double-buffering"]
            B6["dispatch_barriers[]<br/>Dispatch pull mbarrier"]
        end

        subgraph "细粒度依赖 (原子计数)"
            C1["l1_full_count[]<br/>per-block token 到达计数<br/>red_add_rel + ld_acq 自旋"]
            C2["l2_full_count[]<br/>per-n_block L1 output 就绪<br/>red_add_rel + ld_acq 自旋"]
            C3["l1_empty_count[]<br/>per-block L1 可重用<br/>red_add + ld_acq 自旋"]
            C4["l2_empty_count[]<br/>per-block L2 可重用<br/>red_add + ld_acq 自旋"]
        end

        subgraph "Warp 内同步"
            D1["__syncwarp()<br/>Warp 内线程同步"]
            D2["ptx::sync_aligned()<br/>SM 内 mbarrier 同步"]
        end
    end

4.2 grid_sync:SM 间全局同步

// deep_gemm/include/deep_gemm/comm/barrier.cuh
template <uint32_t kNumSMs, uint32_t kGridSyncIndex = 0, typename sync_scope_t>
CUTLASS_DEVICE void grid_sync(const layout::Workspace& workspace,
                              const uint32_t& sm_idx, const uint32_t& thread_idx,
                              const sync_scope_t& sync_scope) {
    static constexpr uint32_t kFinishSumTag = 0x80000000u;
    sync_scope();
    if (thread_idx == 0) {
        const auto count_ptr = workspace.get_grid_sync_count_ptr<kGridSyncIndex>();
        const auto old_value = ptx::atomic_add_rel(
            count_ptr, sm_idx == 0 ? (kFinishSumTag - (kNumSMs - 1)) : 1);
        uint32_t new_value;
        do {
            new_value = ptx::ld_acq(count_ptr);
        } while (((new_value ^ old_value) & kFinishSumTag) == 0);
    }
    sync_scope();
}

与 DeepEP 的对比:
- DeepEP 使用 cooperative_groups::this_grid().sync()(硬件支持的 grid sync)
- DeepGEMM 使用 atomic_add_rel + ld_acq 自旋(软件实现的 grid sync)
- 两者功能相同,但 DeepGEMM 的实现更灵活(支持多 index、超时检测)

// deep_gemm/include/deep_gemm/comm/barrier.cuh
template <uint32_t kNumRanks, uint32_t kNumSMs, uint32_t kNumThreads, uint32_t kGridSyncIndex, uint32_t kTag, typename sync_scope_t>
CUTLASS_DEVICE void nvlink_barrier(const layout::Workspace& workspace,
                                   const layout::SymBuffer<kNumRanks>& sym_buffer,
                                   const uint32_t& sm_idx, const uint32_t& thread_idx,
                                   const sync_scope_t& sync_scope,
                                   const bool& sync_prologue = true,
                                   const bool& sync_epilogue = true) {
    // 1. Grid sync before NVLink signaling
    if (sync_prologue)
        grid_sync<kNumSMs, kGridSyncIndex>(workspace, sm_idx, thread_idx, sync_scope);

    // 2. NVLink cross-rank barrier, only SM 0 participates
    if (sm_idx == 0) {
        auto* counter_ptr = workspace.get_nvl_barrier_counter_ptr();
        const auto status = (*counter_ptr) & 3;
        const auto signal_phase = status & 1, signal_sign = status >> 1;
        auto* signal_ptr = workspace.get_nvl_barrier_signal_ptr(signal_phase);

        // Send signals to remote ranks
        if (thread_idx < kNumRanks)
            ptx::red_add_rel_sys(sym_buffer.map(signal_ptr, thread_idx), signal_sign ? -1 : 1);
        sync_scope();

        // Update status and wait arrival
        if (thread_idx == 0) {
            ptx::red_add(counter_ptr, 1);
            const int target = signal_sign ? 0 : static_cast<int>(kNumRanks);
            while (ptx::ld_acq_sys(signal_ptr) != target) { /* spin */ }
        }
    }

    // 3. Grid sync after NVLink completion
    if (sync_epilogue)
        grid_sync<kNumSMs, kGridSyncIndex>(workspace, sm_idx, thread_idx, sync_scope);
}

4.4 mbarrier-based Producer-Consumer(等效 FIFO)

DeepGEMM 的核心创新是使用 mbarrier + double-buffering 实现 FIFO 语义:

// deep_gemm/include/deep_gemm/impls/sm100_fp8_fp4_mega_moe.cuh

// Barrier 定义
using Barrier = cutlass::arch::ClusterTransactionBarrier;

// 核心 barrier 数组
Barrier full_barriers[kNumStages];      // TMA load 完成信号
Barrier empty_barriers[kNumStages];     // Consumer 释放信号
Barrier tmem_full_barriers[kNumEpilogueStages];  // TMEM 累积完成
Barrier tmem_empty_barriers[kNumEpilogueStages]; // TMEM 可重用
Barrier combine_barriers[kNumEpilogueWarps * 2]; // Combine double-buffering
Barrier dispatch_barriers[kNumDispatchWarps];   // Dispatch pull mbarrier

Producer-Consumer 协议:

sequenceDiagram
    participant P as Producer (TMA Load Warp)
    participant B as full_barrier / empty_barrier
    participant C as Consumer (MMA Issue Warp)

    P->>B: arrive_and_expect_tx(size)<br/>TMA 加载完成
    C->>B: wait(phase)<br/>等待数据就绪
    C->>C: 消费数据(执行 UMMA)
    C->>B: arrive(0)<br/>释放 buffer
    P->>B: wait(phase ^ 1)<br/>等待 buffer 可重用
    P->>P: 加载下一批数据

关键代码:

// Producer (TMA Load Warp): 加载数据并 signal
shared_storage.full_barriers[stage_idx].arrive_and_expect_tx(
    sizeof(SharedStorage::smem_a[0]) * 2 + sizeof(SharedStorage::smem_sfa[0]) * 2);

// Consumer (MMA Issue Warp): 等待数据就绪
shared_storage.full_barriers[stage_idx].wait(phase);

// Consumer 完成后释放 buffer
shared_storage.empty_barriers[stage_idx].arrive(0u);

// Producer 等待 buffer 可重用
shared_storage.empty_barriers[stage_idx].wait(phase ^ 1);

4.5 细粒度依赖:原子计数实现流式

DeepGEMM 使用 原子计数 实现 per-block 粒度的流式处理:

// Dispatch Warp: 每完成一个 token 的 pull,增加 arrival count
ptx::red_add_rel(
    workspace.get_l1_full_count_ptr(pool_block_idx % kNumRingBlocks), 
    is_last_token ? BLOCK_M - (token_idx_in_expert % BLOCK_M) : 1u
);

// TMA Load Warp (Linear1): 等待整个 block 的 token 全部到达
if (task_info.block_phase == sched::BlockPhase::Linear1) {
    const auto ptr = workspace.get_l1_full_count_ptr(block_idx);
    const auto num_expected_tokens = BLOCK_M * (pool_block_idx / kNumRingBlocks + 1);
    while (ptx::ld_acq(ptr) != num_expected_tokens);  // 自旋等待
}

// Linear2: 等待所需的 L1 output 全部就绪
if (task_info.block_phase == sched::BlockPhase::Linear2) {
    const auto ptr = workspace.get_l2_full_count_ptr(block_idx);
    const auto num_expected_blocks = (L2_SHAPE_K / BLOCK_N) * 2 * (pool_block_idx / kNumRingBlocks + 1);
    while (ptx::ld_acq(ptr) != num_expected_blocks);
}

4.6 DeepGEMM 的同步模式总结

同步原语 用途 粒度 类型
grid_sync SM 间 Grid 同步 所有 SM Barrier
nvlink_barrier 跨 Rank NVLink 同步 所有 Rank Barrier
full_barriers TMA load 完成信号 per-stage FIFO (mbarrier)
empty_barriers Consumer 释放信号 per-stage FIFO (mbarrier)
tmem_full/empty TMEM 累积/释放 per-stage FIFO (mbarrier)
l1_full_count Token 到达计数 per-block 原子计数
l2_full_count L1 output 就绪 per-n_block 原子计数
l1_empty_count L1 可重用 per-block 原子计数
l2_empty_count L2 可重用 per-block 原子计数
__syncwarp Warp 内同步 warp Warp sync
ptx::sync_aligned SM 内跨 warp 同步 SM 内 mbarrier

关键结论:DeepGEMM 使用 mbarrier + double-buffering 实现了与 FIFO 完全等效的流式语义,同时使用原子计数实现细粒度依赖。


5. 对比分析:DeepEP vs DeepGEMM

5.1 同步机制对比

维度 DeepEP DeepGEMM Mega MoE
全局 SM 同步 this_grid().sync() atomic_add_rel + ld_acq 自旋
跨 Rank 同步 NCCL signal/wait red_add_rel_sys + ld_acq_sys 自旋
数据流同步 mbarrier(TMA 内部) mbarrier + double-buffering(FIFO)
细粒度依赖 无 原子计数(l1/l2 count)
FIFO 形式 无显式 FIFO 隐式 mbarrier + shared memory
Buffer 层级 多层(Token→Dispatch→Chunk→Receive→Expert) 少层(L1 Pool + L2)
通信粒度 Chunk(多 token 聚合) Per-Token(单 token 粒度)
跨节点通信 RDMA(显式) NVLink(Symmetric Memory 隐式)

5.2 同步原语实现对比

原语 DeepEP 实现 DeepGEMM 实现
Grid Sync cooperative_groups::this_grid().sync() atomic_add_rel + ld_acq 自旋
NVLink Barrier red_add_rel_sys + ld_acq_sys 自旋 red_add_rel_sys + ld_acq_sys 自旋
mbarrier arrive mbarrier.arrive.expect_tx.shared::cta.b64 ClusterTransactionBarrier.arrive_and_expect_tx
mbarrier wait mbarrier.try_wait.parity.shared::cta.b64 ClusterTransactionBarrier.wait
原子操作 atomicAdd_block, atomicAdd ptx::atomic_add_rel, ptx::red_add_rel

5.3 时序图对比

DeepEP 的同步模式(Barrier 主导):

sequenceDiagram
    participant S as Source GPU
    participant N as Network
    participant R as Remote GPU

    S->>S: Dispatch (per-token TMA load/store)
    S->>S: gpu_barrier (this_grid().sync + NCCL signal)
    N->>N: RDMA transfer
    R->>R: gpu_barrier (this_grid().sync + NCCL wait)
    R->>R: Expert GEMM
    R->>R: gpu_barrier (this_grid().sync + NCCL signal)
    N->>N: RDMA transfer
    S->>S: gpu_barrier (this_grid().sync + NCCL wait)
    S->>S: Combine (per-token reduce)

DeepGEMM 的流式模式(FIFO 主导):

sequenceDiagram
    participant D as Dispatch Warp
    participant L1 as L1 Token Buffer
    participant G1 as Linear1 GEMM
    participant L2 as L2 Acts Buffer
    participant G2 as Linear2 GEMM
    participant C as Combine Warp

    D->>L1: pull token + red_add_rel l1_full_count
    L1->>G1: TMA Load Warp 等待 l1_full_count
    G1->>G1: UMMA (full_barrier/empty_barrier)
    G1->>L2: TMA Store + red_add_rel l2_full_count
    L2->>G2: TMA Load Warp 等待 l2_full_count
    G2->>G2: UMMA (full_barrier/empty_barrier)
    G2->>C: NVLink 写入 combine_token_buffer
    C->>C: Top-K Reduce

5.4 FIFO 语义对比

DeepEP(无显式 FIFO) DeepGEMM(等效 FIFO)
Chunk Buffer(显式队列) smem_a/smem_b/smem_cd(shared memory buffer)
写入 Chunk Buffer full_barriers[i].arrive_and_expect_tx()
从 Chunk Buffer 读取 full_barriers[i].wait(phase)
Chunk Buffer 空位可用 empty_barriers[i].arrive() + wait(phase ^ 1)
Chunk 粒度 BLOCK 粒度(BLOCK_M × BLOCK_K)

6. 跨引用分析:FIFO 与其他概念的关系

6.1 FIFO 与 Warp Specialization(Agent 3)

概念 关系
Warp Specialization 将不同阶段分配给不同 Warp 角色
FIFO 实现 Warp 角色之间的数据传递
协同 Warp Spec 是"角色分离",FIFO 是"角色间通信"

DeepEP 中的体现:
- Notify Warps:元数据通知
- Dispatch Warps:数据搬运
- 两者通过 gpu_barrier 同步(不是 FIFO)

DeepGEMM 中的体现:
- Dispatch Warps:Token 路由 + NVLink Pull
- TMA Load Warps:数据加载
- MMA Issue Warp:矩阵乘法
- Epilogue Warps:后处理 + Combine
- 各角色通过 full_barriers/empty_barriers 解耦(FIFO 语义)

6.2 FIFO 与 Chunk Streaming(Agent 9)

概念 关系
Chunk Streaming 数据以 Chunk 粒度流过 pipeline
FIFO Chunk Streaming 的底层实现机制
区别 Chunk Streaming 强调"粒度",FIFO 强调"解耦"

DeepEP 的 Chunk Streaming:
- Token 聚合为 Chunk 后通信
- Chunk Buffer 作为显式 FIFO 队列
- 但同步仍依赖 gpu_barrier

DeepGEMM 的 Chunk Streaming:
- Per-Token 粒度(更细粒度)
- mbarrier + double-buffering 实现流式
- 无需等待整个 Batch

6.3 FIFO 与 Normal vs Low-Latency(Agent 7)

模式 DeepEP Normal DeepEP Low-Latency DeepGEMM
Chunk 关键 减少 Per-Token
Pipeline 深 浅 深(融合 kernel)
FIFO 形式 Chunk Buffer 无 mbarrier + smem
同步 Barrier 主导 Barrier 主导 FIFO 主导

关键洞察:
- DeepEP 的 Normal/Low-Latency 都使用 Barrier 主导 的同步
- DeepGEMM 通过 FIFO 主导 的同步实现了 Normal 模式的流式处理
- DeepGEMM 没有 Low-Latency 模式,因为它通过 per-token 粒度天然实现了低延迟


7. 核心结论

7.1 博客理论的准确性评估

博客断言 DeepEP DeepGEMM 评估
"Send → FIFO → Forward" ❌ 无 FIFO ✅ mbarrier FIFO 部分准确
"无需等待整个 Batch" ❌ Barrier 等待 ✅ per-token 流式 部分准确
"每个阶段只关心自己的读写" ❌ Barrier 同步 ✅ mbarrier 解耦 部分准确
"FIFO 本质:同步→流式" ❌ 仍为同步 ✅ 流式 部分准确

结论:博客描述的 FIFO 模型更贴近 DeepGEMM 的实现,而非 DeepEP。DeepEP 使用的是 Barrier 主导 的同步模式,而非 FIFO。

7.2 同步机制的本质差异

维度 DeepEP DeepGEMM
同步范式 Barrier(全局同步) FIFO(局部解耦)
数据流 显式拷贝 + Barrier 零拷贝 + mbarrier
粒度 Chunk(粗粒度) Per-Token(细粒度)
延迟 高(Barrier 等待) 低(流式处理)
吞吐 高(Chunk 聚合) 高(细粒度流水线)

7.3 设计哲学对比

DeepEP 的设计哲学:
- 通信与计算分离:Dispatch/Combine 是独立 kernel
- Chunk 聚合:减少通信次数,提高带宽利用率
- Barrier 同步:简单可靠,但引入全局等待

DeepGEMM 的设计哲学:
- 通信与计算融合:单个 kernel 完成所有操作
- Per-Token 粒度:最小化延迟
- FIFO 解耦:各阶段独立运行,无需全局同步

7.4 同步原语选择的原因

因素 DeepEP DeepGEMM
硬件代际 SM90(Hopper) SM100(Blackwell)
通信硬件 NCCL + RDMA NVLink + Symmetric Memory
Kernel 模式 多 kernel 协作 单 kernel 融合
同步需求 跨 kernel barrier 跨 stage FIFO
mbarrier 用途 TMA 内部同步 FIFO 实现

8. 完整 Pipeline 数据流图

8.1 DeepEP 的 Barrier 主导 Pipeline

graph TB
    subgraph "DeepEP Normal Kernel"
        direction TB

        subgraph "Phase 1: Notify"
            N1["Notify Warps<br/>元数据交换"]
            N2["gpu_barrier<br/>全局同步"]
            N1 --> N2
        end

        subgraph "Phase 2: Dispatch"
            D1["Dispatch Warps<br/>per-token TMA load/store"]
            D2["gpu_barrier<br/>全局同步"]
            D1 --> D2
        end

        subgraph "Phase 3: Expert GEMM"
            E1["外部 GEMM kernel<br/>(不在 DeepEP 内)"]
            E2["隐式同步<br/>(kernel 边界)"]
            E1 --> E2
        end

        subgraph "Phase 4: Combine"
            C1["Combine Warps<br/>per-token reduce"]
            C2["gpu_barrier<br/>全局同步"]
            C1 --> C2
        end

        N2 --> D1
        D2 --> E1
        E2 --> C1
    end

    style N2 fill:#ffcdd2
    style D2 fill:#ffcdd2
    style E2 fill:#ffcdd2
    style C2 fill:#ffcdd2

8.2 DeepGEMM 的 FIFO 主导 Pipeline

graph TB
    subgraph "DeepGEMM Mega MoE (Single Kernel)"
        direction TB

        subgraph "Phase 1: Dispatch"
            D1["Dispatch Warps<br/>Token 路由 + NVLink Pull"]
            D2["grid_sync<br/>SM 间同步"]
            D3["nvlink_barrier<br/>跨 rank 同步"]
            D4["pull token<br/>+ red_add_rel l1_full_count"]
            D1 --> D2 --> D3 --> D4
        end

        subgraph "Phase 2: Linear1 GEMM"
            L1A["TMA Load Warp (A)<br/>等待 l1_full_count"]
            L1B["TMA Load Warp (B)<br/>加载 weight"]
            L1C["MMA Issue Warp<br/>full_barrier/empty_barrier"]
            L1A --> L1C
            L1B --> L1C
        end

        subgraph "Phase 3: L1 Epilogue"
            E1["TMEM Load<br/>SwiGLU + FP8 Cast"]
            E2["TMA Store<br/>写入 l2_acts"]
            E3["red_add_rel<br/>l2_full_count"]
            E1 --> E2 --> E3
        end

        subgraph "Phase 4: Linear2 GEMM"
            L2A["TMA Load Warp (A)<br/>等待 l2_full_count"]
            L2B["TMA Load Warp (B)<br/>加载 l2_weights"]
            L2C["MMA Issue Warp<br/>full_barrier/empty_barrier"]
            L2A --> L2C
            L2B --> L2C
        end

        subgraph "Phase 5: L2 Epilogue + Combine"
            C1["TMEM Load<br/>BF16 Output"]
            C2["NVLink 写入<br/>combine_token_buffer"]
            C3["nvlink_barrier<br/>跨 rank 同步"]
            C4["Top-K Reduce<br/>累加"]
            C1 --> C2 --> C3 --> C4
        end

        D4 -->|"l1_full_count<br/>per-block"| L1A
        E3 -->|"l2_full_count<br/>per-n_block"| L2A
        C2 -->|"隐式就绪"| C4
    end

    style D2 fill:#c8e6c9
    style D3 fill:#c8e6c9
    style L1C fill:#bbdefb
    style L2C fill:#bbdefb
    style C3 fill:#c8e6c9

9. 关键代码索引

9.1 DeepEP 关键代码

文件 行号 内容
comm.cuh 208-264 gpu_barrier 实现
comm.cuh 88-129 nvlink_barrier_wo_local_sync
comm.cuh 131-181 gin_barrier_wo_local_sync
ptx.cuh 56-90 mbarrier 初始化、arrive、wait
ptx.cuh 124-148 TMA load/store
dispatch.cuh 73-76 初始 barrier
dispatch.cuh 270-394 Dispatch 主循环(mbarrier 使用)
dispatch.cuh 397-400 最终 barrier
combine.cuh 77-80 初始 barrier
combine.cuh 239-242 最终 barrier

9.2 DeepGEMM 关键代码

文件 行号 内容
barrier.cuh 21-44 grid_sync 实现
barrier.cuh 46-89 nvlink_barrier 实现
sm100_fp8_fp4_mega_moe.cuh 79-80 Barrier 类型定义
sm100_fp8_fp4_mega_moe.cuh 196-203 Barrier 数组定义
sm100_fp8_fp4_mega_moe.cuh 237-268 Barrier 初始化
sm100_fp8_fp4_mega_moe.cuh 692-704 l1/l2_full_count 等待
sm100_fp8_fp4_mega_moe.cuh 706-733 TMA Load Warp (Tokens)
sm100_fp8_fp4_mega_moe.cuh 757-792 TMA Load Warp (Weights)
sm100_fp8_fp4_mega_moe.cuh 859-911 MMA Issue Warp
sm100_fp8_fp4_mega_moe.cuh 987-1191 L1 Epilogue
sm100_fp8_fp4_mega_moe.cuh 1192-1305 L2 Epilogue + Combine

10. 参考

  • 博客原文:/tmp/deep_ep_blog_text.txt Section 6
  • DeepEP 源码:/Users/backyes/work/claude_workspace/deepgemm_research/deep_ep/
  • DeepGEMM 源码:/Users/backyes/work/claude_workspace/deepgemm_research/DeepGEMM/
  • 前置分析:docs/05_04_fifo_pipeline.md
  • CUTLASS ClusterTransactionBarrier 文档
  • NVIDIA SM90 / SM100 架构手册