Skip to content

屏障和同步标志 — 剖面图

二进制: extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(构建 ID 89edbbe81c5b328a958fe628a9f2207d,构建 libtpu_lts_20260413_b_RC00.text VMA == 文件偏移 0xe63c000.rodata VMA == 文件偏移)。 状态: 重新实现等级映射 · 证据等级: 已确认(字节锚定)— BarrierType 枚举、InferBarrierConfig 规范化器树和三个 TC 保留时隙 SFLAG 公式是字节精确的;每代 SFLAG 范围的字面量是嵌入式内存文件依赖项(低,请参阅第 5 节)· 第 XIII 部分 — On-Pod Collectives & Barriers / SFLAG & Barriers · 返回索引

摘要

TPU 上的 屏障 不是 CPU 内存栅栏,也不是操作系统 futex。它是程序中一组核心(或芯片)必须会合的点,完全在芯片的同步标志(SFLAG)原子计数器层之上实现(请参阅 SFLAG 同步标志层)。每个屏障都绑定到一个保留的 SFLAG 编号;核心向其发出信号(TensorCore 上为 tpu.sem_signal,SparseCore 上为 sc_tpu.sync_add)并对其进行旋转等待(tpu.sem_wait / sync_wait),直到每个参与者都到达。没有内核参与,也没有共享锁对象——整个集合点是 SFLAG MemorySpace 中的一个计数器,加上对等集上 scf.for 循环中包装的一对 MLIR 操作。

编译器选择集体通过小型类型模型获得的哪个障碍。每个集合在其 HLO BackendConfig 中都携带一条 BarrierConfig 子消息(一对 {BarrierType type, int id}),用于命名每核 SFLAG 块内的屏障类型和槽。两次传球触及该场地。 生产者TensorCoreBarrierAssignment::DetermineBarrierConfigForKey @0x109c6fa0,由贪婪的图形着色引擎 (屏障着色) 提供,决定哪些集体可以共享屏障 id。 标准化器InferBarrierConfig @0x1376c240,它在钳形融合发射时间运行,并且当它可以证明集体的通信集是真正的多参与者时,将每键 CUSTOM 障碍“降级”到更便宜的 GLOBALREPLICA (推断屏障配置)。然后,所选的 BarrierConfigCustomKernelEmitter::Emit @0x1321ad60 读回,并降低为 SFLAG memref + 信号/等待操作 (屏障到 SFLAG 的绑定)。

此页面是该子系统的映射:SFLAG 屏障模型、BarrierType 枚举、生产者→标准化器→降低流程以及每代 SFLAG 内存映射。每个算法——着色引擎、SFLAG 绑定、每核保留槽布局、SparseCore 树屏障——都是 barrier/ 下的 同级页面;此页面链接它们并且不重复它们的字节级派生。跨主机 (DCN) 屏障是一个完全不同的子系统:请参阅 Megascale

重新实现,合约为:

  • **SFLAG模型:**屏障是一个保留的SFLAG编号加上一个signal-all-then-wait协议;没有锁对象。该数字来自 Target::Init / SparseCoreTarget::Init 雕刻的每核保留块。
  • BarrierType 枚举 ({INVALID, GLOBAL, REPLICA, CUSTOM, MEGACORE} = 0..4) 以及允许每个生产者写入的值 — MEGACORE(4) 在枚举中保留,但没有 BarrierConfig 生产者写入它
  • 降低流程: BarrierConfig(原型,在BackendConfig中)→着色/DetermineBarrierConfigForKeyInferBarrierConfig标准化→BarrierConfig::id→每代的芯片SFLAG编号,通过保留块公式。
  • 每代 SFLAG 地图: TC 块保留 5 个命名的顶部插槽 (count = |compiler_reserved| − 5); SC 区块不保留任何内容。区块几何形状与生成无关;每个 (codename, deployment-name) 芯片配置内存文件中只有文字整数有所不同。
阻隔基板芯片SFLAG原子计数器层(SFLAG 同步标志层)
BarrierType 枚举BARRIER_INVALID=0, GLOBAL=1, REPLICA=2, CUSTOM=3, MEGACORE=4(MEGACORE从未生产过)
配置运营商BackendConfig.BarrierConfig {type @+0x20, id, hasbits @+0x10}(每个 HLO 原始子消息)
制作人(着色)TensorCoreBarrierAssignment::DetermineBarrierConfigForKey @0x109c6fa0
归一化器(融合发射)InferBarrierConfig @0x1376c240(8个钳形融合呼叫者)
SFLAG 降低CustomKernelEmitter::Emit @0x1321ad60MaybeInsertGlobalBarrier @0x1321ac20 / RunPasses @0x13202780
TC保留块Target+0x8c0 底座 / Target+0x8c4 计数 (= |CR_TC| − 5); 5 个已命名的顶级插槽
SC保留块SparseCoreTarget+0x1d0 底座 / +0x1d4 计数(= |CR_SC|,无 −5)
SFLAG 范围源TpuChipConfigProto.special_purpose_sync_flags 字段 13 → .compiler_reserved 重复 int32

1. TPU上的屏障是什么

屏障子系统位于片上 SFLAG 层的顶部——一个带有 MemorySpace 标记的原子计数器的小型阵列。屏障保留一个 SFLAG 编号并在其上运行 signal-all-then-wait 树协议;两个基板上的 MLIR 原语为 AllocateAtOffsetOp @0x145a5aa0MemorySpaceAttr(sflag) @0x1458ff20,它在保留的 SFLAG 偏移处实现了 memref。这两种基板的不同之处仅在于它们所包裹的原子操作系列:

text
TensorCore barrier                       SparseCore barrier
  AllocateAtOffsetOp(MemorySpace::sflag)   AllocateAtOffsetOp(MemorySpace::sflag)
  scf.for peer in cores:                   (per-ring)
    tpu.sem_signal  @0x14b442e0              sc_tpu.sync_add
  scf.for peer in cores:                     sc_tpu.sync_wait
    tpu.sem_wait    @0x14b45460
```text

重新实现者的两个后果:

- **屏障 *是* 一个 SFLAG 编号。** 运行时没有单独的屏障对象 — `BarrierConfig.id` 在降低后是保留的每核 SFLAG 块的索引 (§5)。分配barrier就意味着预留SFLAG slot;释放一个意味着它返回到池中。因此,整个障碍分配问题是一个 SFLAG 编号分配问题。
- **集合点纯粹是合作性的。**每个参与核心都发出信号(撞击计数器)并等待(旋转直到计数器达到参与者计数)。错误的参与者计数或重复的 ID 会默默地陷入死锁——发出的操作中没有超时。生产者的工作 (§3) 是确保不会为两个同时存在的集体分配相同的 id。

> **注意 —** SFLAG 数字空间在所有屏障类型和两种基材之间“共享”。 TC 全局屏障 (`tpu.sem_*`)、TC 每键屏障和 SparseCore 每环屏障 (`sc_tpu.sync_*`) 均取自同一保留芯片 SFLAG 块(TC 为 `Target+0x8c0/+0x8c4`,SC 为 `SparseCoreTarget+0x1d0/+0x1d4`)。它们在硬件级别的唯一区别是原子操作系列以及它们索引的核心块。

---

## 2. `BarrierType` 枚举和 `BarrierConfig`

编译器发出的每个屏障都标有五个 `BarrierType` 值之一。该枚举是每个集合体的 `BackendConfig` 的 `BarrierConfig` 子消息中携带的原始枚举;数值是 protobuf 字段值,从生产者和标准化器中的 `movl $N,-0x30` / `cmp $N` 字节模式恢复。命名字符串 `"barrier.barrier_type() != BarrierType::BARRIER_INVALID"`(`InferBarrierConfig` 第 115 行的 RetCheck)将 `INVALID` 枚举器锚定在 0。

| 值 | 枚举器 | 含义 | 降低 SFLAG |
|---|---|---|---|
| 0 | `BARRIER_INVALID` | 哨兵/未设置;总是被两个接触点拒绝 | — |
| 1 | `GLOBAL` | 全核器件全屏障; `id = -1`哨兵 | `base + count + 4` (`GetGlobalBarrierSyncFlagNumber` @`0x1d60f420`) |
| 2 | `REPLICA` | 副本组内树屏障;共享一个id | `base + id`(由规范器 `id = count − 1` 设置时顶部保留的每个 id 插槽) |
| 3 | `CUSTOM` | 每键专用道闸;着色指定新的 `id` | `base + id`(每个键插槽,[屏障到 SFLAG 的绑定](barrier-to-sflag-binding.md)) |
| 4 | `MEGACORE` | 每芯片两个张量核屏障;保留在枚举中 | `base + count`(`GetMegacoreBarrierSyncFlagNumber` @`0x1d60f4e0`、`Megacore()` 门控) |

`BarrierConfig` 本身是一个小原型:类型字段位于运行时消息的字节偏移 `+0x20` 处,存在位于 `+0x10` 处(`0x3` 中的标准化器或用于标记类型和 id 存在)。当集合体没有 `barrier_config` 子消息时,两个接触点都会回退到默认实例 `BarrierConfig_globals_` @`0x223a9450`。

> **QUIRK —** `MEGACORE(4)` 存在于枚举中,并具有实时 SFLAG 访问器(`GetMegacoreBarrierSyncFlagNumber`,在 `TpuChipConfig::Megacore()` 上门控),但**此版本中没有 `BarrierConfig` 生产者写入值 4**。着色制作者只写了`{1,2,3}`;规范化器仅写入 `{1,2}` (并且永远不会远离已设置的 GLOBAL/REPLICA)。驱动关闭所有五个值的重新实现将为配置生成端提供一个死的 `case 4` - 兆核插槽直接由硬件屏障发射消耗,而不是由 `BarrierConfig` 消耗。通过完整的 E8 外部参照扫描确认:任何生产商的类型字段中都没有 `movl $4`。

---

## 3.下降流量

一个集体的屏障经历三个阶段:**生产者**选择 `BarrierType` 和 `id` 并将其写入 HLO `BackendConfig`; **标准化器**可以在融合发射时重写它; **发射器**读回它并将其降低到 SFLAG memref + 信号/等待。这两个编写器是不同的,在不同的管道阶段运行,并且从不共享状态——它们仅通过 `BackendConfig` 原型字段进行通信。

```text
HLO collectives  (all-reduce / all-gather / reduce-scatter / collective-permute / all-to-all)

  [P]  PRODUCER — TensorCoreBarrierAssignment::Run  (HLO barrier-assignment pass)
        │   ├─ BarrierColoring::Run @0x109cf600 / 0x109d1a60   (greedy graph coloring; §3.1)
        │   │     two passes (collective-permute policy + async-barrier policy) →
        │   │     interference graph over live async ranges → first-fit color → conflict set
        │   └─ DetermineBarrierConfigForKey @0x109c6fa0(key, config, has_conflict)
        │         writes BarrierConfig {GLOBAL(1) | CUSTOM(3 fresh) | REPLICA(2 shared)} → BackendConfig

  [N]  NORMALISER — InferBarrierConfig @0x1376c240   (per pincer fusion, 8 callers; §3.2)
        │   reads BackendConfig.BarrierConfig; if multi-participant & CUSTOM(3):
        │     channel_id present?  → GLOBAL(1), id=-1
        │     else                 → REPLICA(2), id = count−1
        │   singleton set → keep; INVALID(0) → RetCheck

  [L]  LOWERING — CustomKernelEmitter::Emit @0x1321ad60   (kernel emit; §3.3)
        │   reads BackendConfig.BarrierConfig back out
        ├─ type 1 (global) → MaybeInsertGlobalBarrier @0x1321ac20
        │                     → AllocateAtOffsetOp(sflag) + scf.for(tpu.sem_signal/sem_wait) tree barrier
        └─ type 2/3 (per-key) → RunPasses @0x13202780
                                → GetSyncFlagForBarrierId → AllocateAtOffsetOp(sflag)


   chip SFLAG number (§5)  →  hardware rendezvous

3.1 Producer — 着色引擎

DetermineBarrierConfigForKey 不单独决定屏障共享;它由贪婪的图形着色引擎 BarrierColoring<Policy>::Run 提供 has_conflict 布尔值。该引擎按 TensorCoreBarrierKey 对所有 TensorCore 集合进行分组,构建一个干扰图,其中两个相同键的异步集合在其 async-start..async-done 生命周期在调用图排序计划中重叠时获得边缘,然后首先为每个键图设置颜色。颜色为0的集体可以共享一个障碍(REPLICA/GLOBAL);被迫使用非零颜色的集体落在冲突集中并获得新的 CUSTOM id。完整的算法——两个策略(collective-permute-start/done 0x24/0x23 与 async-barrier 自定义调用)、冲突谓词和首次适应搜索——位于 屏障着色 中。

这是与 SparseCore 的结构差异,SparseCore 在静态环配置哈希上消除障碍,没有调度重叠的概念。 TensorCore 在“实时”干扰图上进行重复数据删除,因此,即使两个具有相同键的集合,如果它们同时处于飞行状态,也会被分成不同的障碍。

3.2 标准化器 — InferBarrierConfig

InferBarrierConfig @0x1376c240 是第二个不同的接触点。当融合的实际通信集形状已知时,它在发射时在八个 RotatedPincer / RotatedPincerShort / AsyncPincer 融合发射器内部运行。它重新读取 HLO BackendConfig.BarrierConfig 并将 CUSTOM 屏障“降级”为更便宜的类型。决策树,针对反编译进行了字节精确验证(cmp/movl 站点已注释):

c
function InferBarrierConfig(target, hlo, strat):              // 0x1376c240
    cfg = hlo->backend_config<BackendConfig>()                // 0xf58e6c0
    if (!cfg.ok()) return RetCheck(line 0x5d)                 // rotated_pincer_fusion_emitter.cc

    bc = cfg.has_barrier_config()                             // hasbit 0x10 @ msg+0x10
       ? cfg.barrier_config()
       : BarrierConfig_globals_                               // default @0x223a9450

    // PREDICATE: is the communicating set multi-participant on either axis?
    multi = (strat->f8 /*+0x8*/ > 1) || (strat->f10 /*+0x10*/ > 1)   // strat[1]>1 || strat[2]>1

    if (multi):
        if (bc.type == CUSTOM /*3*/):                         // cmp $3
            if (hlo->channel_id().has_value()):               // channel_id @0x1e59ff80, dl==1
                bc.type = GLOBAL /*1*/;  bc.id = -1           // channelled collective → device-global
            else:
                bc.type = REPLICA /*2*/                       // within-replica collective
                bc.id   = target.Target[0x8c4] - 1           // = count − 1, the top usable TC id
                bc.set_has_type_and_id()                      // hasbit |= 3
        else if (bc.type == INVALID /*0*/):
            return RetCheck(line 0x73, "...!= BarrierType::BARRIER_INVALID")
        // else (already GLOBAL/REPLICA) → keep
    else:                                                     // SINGLETON set on both axes
        if (bc.type == INVALID /*0*/): return RetCheck(line 0x73)
        // else keep CUSTOM as-is

    out.barrier_config = bc;  return OK                       // movq $1,(rbx)
```text

语义:如果集体携带 `channel_id`(需要全核屏障的跨模块/跨设备通道集体),则真正多参与者集体上的 `CUSTOM` 屏障将折叠为更便宜的共享屏障 - `GLOBAL`(带有哨兵 `id = -1`),或 `REPLICA`(副本组内树屏障,固定到最后一个可用的 TC id,`count − 1`)(如果没有)。 *单例*集(集体是退化/单核)上的 `CUSTOM` 屏障保持不变。 `INVALID` 始终被拒绝。字节精确的主体 — 包括 `*((int *)a2 + 561) - 1` (`Target+0x8c41`) REPLICA id 且不存在任何 `movl $4` — 位于 [推断屏障配置](infer-barrier-config.md) 中。

> **GOTCHA —** 谓词输入 `Strategy+0x8` / `Strategy+0x10` 是钳形集体通信集的两轴参与者计数(第 0 阶段 /1 阶段环或副本组大小)。偏移量是字节确认的(每个偏移量都是 `cmpq $1`),但字段 *names* 来自 StrategyND 融合上下文,而不是来自结构描述符 - 将“环长度与副本组计数”读数视为推断。 *行为* (`>1 on either axis ⇒ downgrade CUSTOM`) 是确定的。

### 3.3 降低 — `CustomKernelEmitter`

在内核发射时,`CustomKernelEmitter::Emit` @`0x1321ad60` 从 `BackendConfig` 中读回 `BarrierConfig` 并将其交给两个连续的下级程序。类型 1(全局)流入 `MaybeInsertGlobalBarrier` @`0x1321ac20`,它遍历 func 操作并构建 `AllocateAtOffsetOp(sflag)` + `scf.for(tpu.sem_signal / tpu.sem_wait)` 树屏障。类型 2/3(每个键)流入 `RunPasses` @`0x13202780`,其嵌套传递到达 `GetSyncFlagForBarrierId` 和 SparseCore `sc_tpu.sync_*` 发射 — 相同的 `AllocateAtOffsetOp(sflag)` 原语,不同的原子操作系列。完全降低、三个 RetCheck 合法性门(`non-communicating custom call` / `skip_device_barrier` / `unsupported core type`)以及全局与每键分叉位于 [屏障到 SFLAG 的绑定](barrier-to-sflag-binding.md) 中,每核窗口位于 [全局屏障窗口](global-barrier-window.md) 中。

---

## 4. 屏障类型(兄弟页面)

生产者可以发出的障碍类型和下降机械都是同级页面。本节为索引;每行都逐字节链接派生它的页面。

| 种类/刻面 | 它是什么 ||
|---|---|---|
| **全球屏障** | `GLOBAL(1)`;所有核心在 `base+count+4` 上会合; `id=-1`哨兵; `tpu.sem_signal`-all-then-`tpu.sem_wait` 树 | [全局屏障窗口](global-barrier-window.md),[树屏障/vSync](tree-barrier-vsync.md) |
| **复制品屏障** | `REPLICA(2)`;副本组内树屏障;共享 id(由规范器设置时为 `count−1`) | [复制品屏障](replica-barrier.md) |
| **TensorCore 屏障** | TC 基板信号/等待屏障及其颜色选择的 `CUSTOM(3)` id | [TensorCore 屏障](tensorcore-barrier.md) |
| **巨核屏障** | `MEGACORE(4)`; `base+count` 上每芯片两个 TensorCore 屏障; `Megacore()`-门控;不是配置生成的 | (仅限访问器;参见§5) |
| **树屏障/垂直同步** | Mosaic 用户区域窗口上的 SparseCore 每核树屏障 | [树屏障/vSync](tree-barrier-vsync.md) |
| **屏障着色** | 决定屏障共享的贪婪干扰图引擎(生产者的 `has_conflict` 输入) | [屏障着色](barrier-coloring.md) |
| **推断屏障配置** | 钳融合器 `CUSTOM → GLOBAL/REPLICA` 标准化器 (§3.2) | [推断屏障配置](infer-barrier-config.md) |
| **屏障 → SFLAG 绑定** | `CustomKernelEmitter` 将 `BarrierConfig` 降低到芯片 SFLAG memref3.3) | [屏障到 SFLAG 的绑定](barrier-to-sflag-binding.md) |
| **专用同步标志** | `compiler_reserved` 系列 + 四个源自每代块的命名标量 (§5) | [专用同步标志](special-purpose-sync-flags.md) |
| **远程 SFLAG 编码器** | ICI 屏障使用的跨芯片 SFLAG 寻址 | [远程 SFLAG 编码器](remote-sflag-encoders.md) |
| **每个代号 `compiler_reserved`** | 每个 `(codename, deployment)` SFLAG 范围整数的文字(memfile 解析) | [按代号编译器保留](per-codename-compiler-reserved.md) |

跨主机兆级 (DCN) 屏障不是该子系统的一部分 — 没有片上屏障传递调用;它是一个单独的编排层([Megascale](../megascale/overview.md))。 *消耗*这些障碍的集体记录在 [集合通信](../collectives/overview.md) 中。

---

## 5. 每代SFLAG内存映射

屏障可以采用的 SFLAG 编号不是硬编码的;它们来自芯片配置中每个核心类型的**保留范围**,被雕刻到 `Target::Init` 的基数/计数块中。完整的原型→运行时→区块链如下;每一代的文字整数是嵌入式内存文件依赖项(低置信度,请参阅 GOTCHA),但*块几何*是独立于生成且字节确认的。

### 5.1 来源:`compiler_reserved`

每核心类型的 SFLAG 范围是 `SpecialPurposeSyncFlags` 原始消息的 `compiler_reserved` 重复 int32 字段,每个 `TpuCoreType` 一个,在 `TpuChipConfigProto.special_purpose_sync_flags`(字段 13)中携带。在运行时,它们落在 `TpuChipConfig+0x2a0` 处的 `EnumMap<TpuCoreType, SpecialPurposeSyncFlags, 3>` 中(跨步 `0x40`,存在位掩码位于 `+0x360`),由 `GetSpecialPurposeSyncFlags(core)` @`0x20afcf40` 访问:

```c
function GetSpecialPurposeSyncFlags(chip_config, core):       // 0x20afcf40
    mask = *(chip_config + 0x360)                             // per-core-type presence bitmask
    if (!(mask >> core & 1)) return NULL                      // bt core,mask; jae → 0
    if (core >= 3) ud1                                        // CHECK core ∈ {0,1,2}
    return chip_config + 0x2a0 + (core << 6)                  // element `core`, 0x40-byte stride

GOTCHA — 索引是 core << 6 = core * 0x40(shl $6EnumMap 的元素步长),不是 ** +core。使用字节索引 +core 的重新实现会读取 kSparseCore/kBarnaCore 的垃圾。 TensorCore 条目 (core=0) 是强制**:如果不存在,Target::Init 会取消引用结果并通过 DieBecauseNull ("chip_config.GetSpecialPurposeSyncFlags(::tpu::TpuCoreType::kTensorCore)") 终止。

SpecialPurposeSyncFlags 消息还携带四个命名标量 SFLAG 编号 — sequencer_overlay (f4)、tile_overlay (f5)、global_barrier_sflag (f6)、local_barrier_sflag (f7) — 在原始偏移量处+0x30..+0x3c。没有单独追踪这些是否存在于运行时元素中(相对于在 FromProto 中被消耗); Target::Init 仅读取 compiler_reserved 向量。请参阅 专用同步标志

5.2 雕刻:Target::Init / SparseCoreTarget::Init

Target::Init @0x1d60fc20 复制 compiler_reserved(TensorCore),检查它是连续的升序 int 范围,然后写入 base = arr[0]Target+0x8c0count = size − 5Target+0x8c4。该范围的前 5 个保留用于指定的屏障槽(第 5.3 节)。 SparseCoreTarget::Init @0x1d612b20compiler_reserved(SparseCore) 执行相同的操作,将其转换为 SparseCoreTarget+0x1d0 / +0x1d4,但没有 −5 — SC 块已满并在 *[SC_base, SC_base+SC_count) 内保留其全局屏障 id。 TC 和 SC 范围在结构上是不相交的(每个核心类型有不同的 SpecialPurposeSyncFlags 消息)。

5.3 TC预留时隙图(−5)

TC 范围的前 5 个插槽是指定的跨核心屏障同步标志。所有三个访问器公式都是字节精确的(this[560] = Target+0x8c0 = 基数,this[561] = Target+0x8c4 = 计数):

插槽配件公式
base+count+0GetMegacoreBarrierSyncFlagNumber @0x1d60f4e0base + count(Megacore() 门控;检查 "…chip_config().Megacore()")
base+count+1(间隙;GetAllReduceSyncFlagNumber(0) 非法 — 检查 phase > 0)base+count+1
base+count+2GetAllReduceSyncFlagNumber(1) @0x1d60f440base + 1 + count + 1(钳InitSyncFlags)
base+count+3GetAllReduceSyncFlagNumber(2) @0x1d60f440base + 2 + count + 1(钳InitSyncFlags)
base+count+4GetGlobalBarrierSyncFlagNumber @0x1d60f420base + count + 4(全局/树屏障)

GetAllReduceSyncFlagNumber(phase)LogMessageFatal 绑定到 0 < phase < 3(第 143/144 行),因此 +1 插槽是永久间隙。可用的每个 id 窗口 [base, base+count)(复制品/自定义 ids,id < count)位于这 5 个窗口的“下方”。

5.4 每代表(参数)

CR_TC = compiler_reserved(TensorCore)CR_SC = compiler_reserved(SparseCore) 用于给定的 (codename, deployment-name) 芯片配置。 每一代的结构都是相同的——只有整数不同:

Gen(代号)TC块(Target+0x8c0/+0x8c4)SC块(SCTgt+0x1d0/+0x1d4)TC top-5 保留(块内)
JF(kJellyfish,v2)base=CR_TC[0]count=|CR_TC|−5base=CR_SC[0]count=|CR_SC|(无 −5)巨型 b+c,间隙 b+c+1,ar1 b+c+2,ar2 b+c+3,glob b+c+4
DF(kDragonfish,v3)相同相同同5槽图
PF(kPufferfish,v4)相同相同同5槽图
VF(kViperfish,v5p)相同相同同5槽图
GL(kGhostlite,v6e)相同相同同5槽图
GF(k6acc60406,v7)相同相同同5槽图

−5Target::Init (add $0xfffffffb) 中的编译时常量,与生成无关:每一代都保留 5 个指定的顶级插槽。 Megacore 部署(megacore*megachip)是指 CoresPerChip(TensorCore) == 2BarrierMegacore 处于活动状态且 base+count megacore 插槽已被占用的部署;其他部署将其保留为未使用。

GOTCHA — 每个 (codename, deployment-name) 整数的文字(CR_TC[0]|CR_TC|CR_SC[0]|CR_SC|)不能从 .rodata 静态提取。它们存在于嵌入式芯片配置 memfile 二进制 pb blob (tpu_chip_config_memfile_{default,megacore,megachip,…}_embed_internal_create @0x20b18fa0..) 中,在运行时通过 FLAGS_deepsea_chip_config_name @0x224714b0 键控的 flat_hash_map<tuple<TpuVersion, name, TpuCoreType>, FileToc*> 进行解析。上面的块几何形状已确认;整数为低(内存文件依赖性)。请参阅 按代号编译器保留

明白了 — 两个附近的 SparseCoreTarget 字段不是 SFLAG 窗口基数。 SparseCoreTarget+0x90TpuCoreParts::SequencerCount(TpuSequencerType=5),每核定序器计数。 +0x1fcGetMemoryReservation → GetUserRegion 长度(马赛克每核树屏障窗口,水母 MemorySpace::kSparseCoreSequencerSmem = 14),不是从 SFLAG 向量中绘制的第三个不相交区域。两者都不是 compiler_reserved 块的一部分。


6. 两个生产者,一个配置字段

值得明确指出的是,BarrierConfig 字段有两个编写器,重新实现者必须保持不同:

制片人运行时写入id 来源
DetermineBarrierConfigForKey @0x109c6fa0HLO 屏障分配通行证(每个键)GLOBAL(1) / CUSTOM(3 fresh) / REPLICA(2 shared)-1(全球)/新鲜/共享密钥 ID
InferBarrierConfig @0x1376c240钳式融合发射(每次融合,8 个调用者)CUSTOM→GLOBAL(1, id=-1)(如果有通道); CUSTOM→REPLICA(2, id=count−1) 如果没有-1(全球)/ count−1(复制品)

DetermineBarrierConfigForKey是HLO通时权威调色制作商。 InferBarrierConfig 是灌注标准化器:当钳形融合的实际参与者集已知时,它仅将 CUSTOM 选择降级为 GLOBAL/REPLICA,并且从不升级或重写已设置的 GLOBAL/REPLICA。两者都没有写 MEGACORE(4)。两个结果都提供相同的降低 (§3.3) → 相同的 SFLAG 数字空间 (§5)。


7. 验证说明

libtpu.so v0.0.40 中的字节精确:

  • InferBarrierConfig @0x1376c240:单例谓词 *((__int64*)a4 + 1) <= 1 && *((__int64*)a4 + 2) <= 1(策略+0x8/+0x10); if (v35 == 3)(定制); channel_id(a3) 然后 v15 == 1v35 = 1(全球),v16 = -1;否则 v35 = 2(复制品),v16 = *((int*)a2 + 561) - 1(目标+0x8c4 - 1);重检线 115 "barrier.barrier_type() != BarrierType::BARRIER_INVALID"任何地方都没有 movl $4 — 准确。
  • GetGlobalBarrierSyncFlagNumber @0x1d60f420this[561] + this[560] + 4 = base + count + 4 — 准确。
  • GetAllReduceSyncFlagNumber @0x1d60f440:检查 phase > 0 / phase < 3this[560] + phase + this[561] + 1 = base + count + phase + 1 — 准确。
  • GetMegacoreBarrierSyncFlagNumber @0x1d60f4e0Megacore() 门控 ("topology_->chip_config().Megacore()")、this[560] + this[561] = base + count — 准确。
  • GetSpecialPurposeSyncFlags @0x20afcf40bt core, *(chip+0x360) 门; core >= 3ud1return chip + 0x2a0 + (core << 6) — 精确(步幅是 core<<6,而不是 +core)。
  • 符号确认:DetermineBarrierConfigForKey(...HloModuleConfig, bool) @0x109c6fa0 和两个 BarrierColoring<…>::Run 策略都存在于反编译中。

[低] 每代 compiler_reserved 整数的文字 (§5.4) — proto 字段、carve 公式和 memfile 查找均已确认,但整数是从嵌入的 binarypb blob 运行时解析的,并且不是静态提取的。 BarrierType 数值 2/4 (REPLICA/MEGACORE) 是从 movl/cmp 字节模式和原始值算术中恢复的;仅 INVALID(0)GLOBAL(1)CUSTOM(3) 显示为命名的 .rodata 字符串。


交叉引用

屏障算法(本节)

同级子系统