屏障和同步标志 — 剖面图
二进制:
extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(构建 ID89edbbe81c5b328a958fe628a9f2207d,构建libtpu_lts_20260413_b_RC00;.textVMA == 文件偏移0xe63c000,.rodataVMA == 文件偏移)。 状态: 重新实现等级映射 · 证据等级: 已确认(字节锚定)—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 障碍“降级”到更便宜的 GLOBAL 或 REPLICA (推断屏障配置)。然后,所选的 BarrierConfig 由 CustomKernelEmitter::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中)→着色/DetermineBarrierConfigForKey→InferBarrierConfig标准化→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 @0x1321ad60 → MaybeInsertGlobalBarrier @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 @0x145a5aa0 和 MemorySpaceAttr(sflag) @0x1458ff20,它在保留的 SFLAG 偏移处实现了 memref。这两种基板的不同之处仅在于它们所包裹的原子操作系列:
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 rendezvous3.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 站点已注释):
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+0x8c4 − 1`) 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 memref (§3.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 strideGOTCHA — 索引是
core << 6=core * 0x40(shl $6—EnumMap的元素步长),不是 **+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+0x8c0,count = size − 5 → Target+0x8c4。该范围的前 5 个保留用于指定的屏障槽(第 5.3 节)。 SparseCoreTarget::Init @0x1d612b20 对 compiler_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+0 | GetMegacoreBarrierSyncFlagNumber @0x1d60f4e0 | base + count(Megacore() 门控;检查 "…chip_config().Megacore()") |
base+count+1 | (间隙;GetAllReduceSyncFlagNumber(0) 非法 — 检查 phase > 0) | base+count+1 |
base+count+2 | GetAllReduceSyncFlagNumber(1) @0x1d60f440 | base + 1 + count + 1(钳InitSyncFlags) |
base+count+3 | GetAllReduceSyncFlagNumber(2) @0x1d60f440 | base + 2 + count + 1(钳InitSyncFlags) |
base+count+4 | GetGlobalBarrierSyncFlagNumber @0x1d60f420 | base + 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|−5 | base=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槽图 |
−5 是 Target::Init (add $0xfffffffb) 中的编译时常量,与生成无关:每一代都保留 5 个指定的顶级插槽。 Megacore 部署(megacore*、megachip)是指 CoresPerChip(TensorCore) == 2 → BarrierMegacore 处于活动状态且 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+0x90是TpuCoreParts::SequencerCount(TpuSequencerType=5),每核定序器计数。+0x1fc是GetMemoryReservation → GetUserRegion长度(马赛克每核树屏障窗口,水母MemorySpace::kSparseCoreSequencerSmem= 14),不是从 SFLAG 向量中绘制的第三个不相交区域。两者都不是compiler_reserved块的一部分。
6. 两个生产者,一个配置字段
值得明确指出的是,BarrierConfig 字段有两个编写器,重新实现者必须保持不同:
| 制片人 | 运行时 | 写入 | id 来源 |
|---|---|---|---|
DetermineBarrierConfigForKey @0x109c6fa0 | HLO 屏障分配通行证(每个键) | 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.sov0.0.40 中的字节精确:
InferBarrierConfig@0x1376c240:单例谓词*((__int64*)a4 + 1) <= 1 && *((__int64*)a4 + 2) <= 1(策略+0x8/+0x10);if (v35 == 3)(定制);channel_id(a3)然后v15 == 1→v35 = 1(全球),v16 = -1;否则v35 = 2(复制品),v16 = *((int*)a2 + 561) - 1(目标+0x8c4 - 1);重检线 115"barrier.barrier_type() != BarrierType::BARRIER_INVALID"; 任何地方都没有movl $4— 准确。GetGlobalBarrierSyncFlagNumber@0x1d60f420:this[561] + this[560] + 4=base + count + 4— 准确。GetAllReduceSyncFlagNumber@0x1d60f440:检查phase > 0/phase < 3;this[560] + phase + this[561] + 1=base + count + phase + 1— 准确。GetMegacoreBarrierSyncFlagNumber@0x1d60f4e0:Megacore()门控 ("topology_->chip_config().Megacore()")、this[560] + this[561]=base + count— 准确。GetSpecialPurposeSyncFlags@0x20afcf40:bt core, *(chip+0x360)门;core >= 3→ud1;return 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字符串。
交叉引用
屏障算法(本节)
- 屏障着色 — 贪婪干涉图引擎为
DetermineBarrierConfigForKey的has_conflict提供数据 - 推断屏障配置 — 钳形融合
CUSTOM → GLOBAL/REPLICA标准化器(全字节精确树) - 屏障到 SFLAG 的绑定 —
CustomKernelEmitter将BarrierConfig降低到芯片 SFLAG memref - 全局屏障窗口 —
base+count+4全局插槽和每核屏障窗口 - 复制品屏障 — 副本组内树屏障 (
REPLICA(2)) - TensorCore 屏障 — TC 基底信号/等待屏障和着色选择的
CUSTOMid - 树屏障/vSync — Mosaic 用户区域窗口上的 SparseCore 每核树屏障
- 专用同步标志 —
compiler_reserved范围 + 四个命名标量(块的原始源) - 按代号编译器保留 —
(codename, deployment)SFLAG 范围整数的文字 - 远程 SFLAG 编码器 — ICI 屏障的跨芯片 SFLAG 寻址
同级子系统
- SFLAG 同步标志层 — 每个势垒都建立在 SFLAG 原子计数器基板上
- 集合通信 - 消耗这些屏障的集体操作(生产者在其管道中运行)
- Megascale — 跨主机 (DCN) 屏障;单独的编排层,而不是片上 SFLAG
- 返回索引