全局屏障 SFLAG 窗口和 REPLICA 路径
二进制:
extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(构建 ID89edbbe81c5b328a958fe628a9f2207d,构建libtpu_lts_20260413_b_RC00;.textVMA == 文件偏移0xe63c000,.rodataVMA == 文件偏移)。 状态: 重新实现级 · 证据等级: 已确认(字节锚定) -GetGlobalBarrierSyncFlagNumber公式、GetBarrierSyncFlag调度、MaybeInsertGlobalBarrier插入门和 REPLICA 树路径(BarrierWithinReplicaGroupStartImpl→VsyncAddRemote) 是字节精确的;每代保留整数的字面量是嵌入式内存文件依赖项(低,请参阅第 5 节)· 第 XIII 部分 — On-Pod Collectives & Barriers / SFLAG & Barriers · 返回索引
摘要
在这个二进制文件中,短语“全局屏障”在两个不同的定序器上命名三个不同的事物,每个事物都来自不相交的保留 SFLAG 区域。此页面拥有实际名称为 GetGlobalBarrierSyncFlagNumber 的页面 - base + count + 4 处的 TensorCore (TC) 保留的全局槽位 - 以及围绕它的两个结构:插入门 CustomKernelEmitter::MaybeInsertGlobalBarrier @0x1321ac20(它决定 是否 SparseCore 函数在不同的 SFLAG 窗口上获得全局屏障)完全),以及 TC GLOBAL 机器共享的 REPLICA(2) 屏障路径 — 通过相同的 net_util::GetBarrierSyncFlag 映射器和 BarrierCoresTree 执行器到达副本组内树屏障。
决定性的结构事实以及此页面存在的原因是 SparseCore Mosaic 发射器的 MaybeInsertGlobalBarrier 从不调用 GetGlobalBarrierSyncFlagNumber。这两者在历史上曾被混为一谈。完整的 .text E8/E9 rel32 外部参照扫描发现 20 个 GetGlobalBarrierSyncFlagNumber @0x1d60f420 的直接调用者,并且 没有一个 位于 SparseCore 自定义内核发射器中。全局SFLAG编号仅属于TC引擎; MaybeInsertGlobalBarrier 插入的 SC 功能级全局屏障在其自己的每核 Mosaic 窗口上运行。
SFLAG 数字公式位于 屏障到 SFLAG 的绑定 上; 按代号编译器保留 上每代的 {base, count} 整数; 推断屏障配置 上的 BarrierConfig 类型分类。此页面拥有全局屏障 SFLAG 窗口保留、MaybeInsertGlobalBarrier 插入门以及全局屏障共享的 REPLICA 路径。
重新实现,合约为:
- 全局 SFLAG 插槽是一个数字,保留在 TC 块的顶部。
GetGlobalBarrierSyncFlagNumber返回base + count + 4— TC 保留范围 (§2) 的五个指定顶部插槽中最高的一个。它是计算出来的,从不存储在BarrierConfig中; GLOBAL 配置带有id = -1。 MaybeInsertGlobalBarrier是一个门,而不是数字源。 它在 SparseCore Mosaic 端运行,读取CustomCallConfig标志 +BarrierConfig.type,并决定是否在 SC 每核窗口上插入函数级树屏障 - 它不计算GetGlobalBarrierSyncFlagNumber(§3)。- 全局槽的使用者集是 TC 引擎。
net_util::GetBarrierSyncFlag(BarrierConfig → SFLAG映射器)、net_util树屏障系列(BarrierCoresTree、BarrierAllCores*)以及内存预留通道 — 所有 TensorCore LLO (§1)。 - REPLICA(2) 是仅 TensorCore 的屏障类型。 它映射到
base + id(不是全局槽),并通过BarrierCoresTree(REPLICATED/PARTITIONED)→BarrierWithinReplicaGroupStartImpl→VsyncAddRemote降低到当前核心的副本组对等体;成员资格是InfoTable文字。 SparseCore RetChecks 类型 2 (§4)。
| 全球 SFLAG 编号 | GetGlobalBarrierSyncFlagNumber @0x1d60f420 = base + count + 4 (this[560]/this[561] = Target+0x8c0/+0x8c4) |
| 预留窗口 | TC块[base, base+count)的前5个插槽; GLOBAL 位于 +count+4,MEGACORE 位于 +count |
| 消费套装 | 20 个直接调用者,所有 TC LLO(net_util::GetBarrierSyncFlag、BarrierCoresTree、BarrierAllCores*、内存预留通行证); 零 SparseCore 发射器调用者 |
BarrierConfig → SFLAG 映射器 | net_util::GetBarrierSyncFlag @0x1c69ad00(全局→base+count+4,其他→base+id) |
| 插入门(SC 马赛克) | CustomKernelEmitter::MaybeInsertGlobalBarrier @0x1321ac20(3 个 RetCheck 门;不调用全局访问器) |
| 复制品生产者 | DetermineBarrierConfigForKey @0x109c6fa0(为单个非分区副本组写入 type=2, id=key id) |
| 复制执行器 | BarrierWithinReplicaGroupStartImpl @0x1c698080 → VsyncAddRemote @0x1d522f40 到 InfoTable 对等点 |
| 来源 TU 锚点 | net_util.cc、barrier_assignment.cc、custom_kernel_emitter.cc、offload_a2a_util.cc |
1.全局SFLAG槽:数量、窗口、消费者
“全局屏障同步标志”是在 TensorCore 保留块顶部保留的单个 SFLAG 编号。它是按需计算,从未在配置字段中携带 - GLOBAL BarrierConfig 存储哨兵 id = -1,并且降低会替换计算的插槽。
1.1 GetGlobalBarrierSyncFlagNumber @0x1d60f420
访问器是两个添加。反编译得到的字节精确:
// xla::jellyfish::Target::GetGlobalBarrierSyncFlagNumber(Target *this) // 0x1d60f420
__int64 GetGlobalBarrierSyncFlagNumber(Target *this) {
return (unsigned int)(*((_DWORD *)this + 561) // Target+0x8c4 = count
+ *((_DWORD *)this + 560) // Target+0x8c0 = base
+ 4);
}
```text
`this[560]` 是 TC reserved-block **base**(`Target+0x8c0`);`this[561]` 是 **count**(`Target+0x8c4`,其中 `count = |compiler_reserved(TensorCore)| − 5`)。结果是 `base + count + 4`,即保留在 per-id 窗口 `[base, base+count)` 之上的五个命名顶部槽位中的**第五个也是最高**。slot 推导、`−5` carve,以及 sibling accessor(`GetMegacoreBarrierSyncFlagNumber` = `base+count`、两个 `GetAllReduceSyncFlagNumber` 槽)在 [Barrier-to-SFLAG Binding](barrier-to-sflag-binding.md) 中推导;per-codename `{base, count}` 整数见 [Per-Codename Compiler-Reserved](per-codename-compiler-reserved.md)。本页不重新推导它们,而是记录该窗口的*消费者*和 GLOBAL/REPLICA *路径*。
> **注意 —** 全局槽**不在**每个 ID 窗口中。 REPLICA(2)/CUSTOM(3) id 满足 `0 <= id < count` 并映射到 `base + id`(§4,§1.2); GLOBAL 是 `base + count + 4`,位于顶部可用 id 上方的四个插槽。两人从不别名。
### 1.2 `net_util::GetBarrierSyncFlag` @`0x1c69ad00` — `BarrierConfig → SFLAG` 映射器
全局槽的主要消费者是 TC 密集集合 `BarrierConfig → SFLAG` 映射器。它在 `BarrierConfig.barrier_type` 的 `[bc+0x20]` 上发货。字节精确:
```c
// net_util::GetBarrierSyncFlag(BarrierConfig const& bc, LloRegionBuilder b) // 0x1c69ad00
int GetBarrierSyncFlag(BarrierConfig const& bc, LloRegionBuilder b) {
int type = *(int*)(&bc + 0x20);
if (type == 1) { // GLOBAL
int n = b.target()->GetGlobalBarrierSyncFlagNumber(); // base + count + 4
return b.SflagImmPtr(n, "global barrier sync flag");
}
if (type == 0) // BARRIER_INVALID
CHECK_FAIL("barrier.barrier_type() != BarrierType::BARRIER_INVALID"); // net_util.cc:2065 (0x811)
// type 2 (REPLICA) / 3 (CUSTOM) / 4 (MEGACORE):
long id = *(long*)(&bc + 0x18);
CHECK(id < *(int*)(b.target() + 0x8c4)); // "barrier.id() < b.target().GetBarrierSyncFlagCount()", :2070 (0x816)
int n = id + *(int*)(b.target() + 0x8c0); // base + id
return b.SflagImmPtr(n, "barrier sync flag number");
}算术:GLOBAL → base + count + 4(保留的全局槽位); 每个 ID (2/3/4) → base + id 与 0 <= id < count。 BARRIER_INVALID(0) 是硬 CHECK-fail;槽值返回时包装为 SflagImmPtr(发射器发出信号/等待的直接 LloValue)。这是 SparseCore GetSyncFlagForBarrierId (id + SC_base) 的 TensorCore 模拟 — 相同的结构,不同的 Target 字段和不同的定序器/操作系列 (屏障到 SFLAG 的绑定)。
GetBarrierSyncFlag有18个直接调用者,全部为xla::jellyfish密集集体发射器(AllGather/RingSum/Binomial/RotatedPincer/CollectivePermute/AllToAll);每个读取由 TensorCoreBarrierAssignment 选择的 HLO BackendConfig.BarrierConfig 并通过 net_util 树屏障助手发出集合点。
1.3 消费者集(20 个调用者;全部 TensorCore)
对 E8/E9 rel32 解析为 0x1d60f420 的整体 .text 扫描发现 20 直接调用站点;每个都解析(通过排序的符号表)为 xla::jellyfish TensorCore LLO / 运行时函数。 SparseCore Mosaic 自定义内核发射器中没有** - 确认 MaybeInsertGlobalBarrier (§3)、EmitScsBarrier 和 EmitAllToAllBarrierStart 从未接触过 Target+0x8c0/+0x8c4。来电者分为四组:
| 集团 | 功能(代表) | 角色 |
|---|---|---|
| A。配置映射器 | net_util::GetBarrierSyncFlag @0x1c69ad00 | BarrierConfig → SFLAG 映射器 (§1.2) — 主要指定消费者 |
| B。树障家族 | BarrierCoresTree @0x1c6a75c0; BarrierAllCoresStartNoReturn @0x1c697b60; BarrierAllCoresJoin @0x1c697e60; BarrierAllCoresWithIdVerification @0x12715900; BarrierCoresWithIdVerificationInternal @0x12715c00; MaybeDistributeStackBaseAddresses @0x1c69ae00 | 运行时ICI/跨核心树屏障(GLOBAL执行器) |
| C。内存保留/分析 | DoMemoryAllocation @0x10a31ee0(×4个站点); LinkAndFinishProgram @0x10a25a20; AllocateHloOutputsInMemorySpace @0x1c439980; ComputeAvailableSyncFlags @0x1c6e42a0; RaceAnalyzerStepper::PreProcessEvent @0x10bb2a60; Processor::Instrument $_1 @0x10c94920; GetReferencedSyncFlags $_1 @0x10c94c60; TpuCompactionIsaEmitterCodegen::Generate @0x1090ece0 | 为 SFLAG 池中的全局槽预留/账户 |
| D。密集集体参考 | AllToAllEmitter::EmitOutputAddressExchange @0x10f00dc0; SC LoweringEmitter::Emit @0x131ce4e0(+1 作为 SFLAG 范围上限,不是屏障消费者) | 直接引用槽位 |
同级 GetMegacoreBarrierSyncFlagNumber @0x1d60f4e0(= base + count、Megacore() 门控)只有 3 个调用者 — SynchronizeProgramDescriptorStatesMegacore、LloRegionBuilder::BarrierMegacore 和 RaceAnalyzerStepper::PreProcessEvent — 即仅百万核倍运行时屏障;没有 BarrierConfig 制作人编写过 MEGACORE(4)(请参阅 推断屏障配置 和 概述 §2 QUIRK)。
BarrierCoresTree@0x1c6a75c0在其主体中调用GetGlobalBarrierSyncFlagNumber并将其包装为SflagImmPtr("global barrier sync flag")— TC 树屏障的 GLOBAL 槽。直接在反编译中验证。
2.三个“全局屏障”,三个保留区域,两个测序仪
因为“全局”这个词被重载,所以重新实现者必须将三个不同的源分开。只有**(c)**是GetGlobalBarrierSyncFlagNumber;该页面拥有 (c) 和产生 (a) 的门。
| # | 什么 | 选择/插入 | SFLAG 编号来源 | 定序器/运算系列 |
|---|---|---|---|---|
| (a) | SC 马赛克 功能级 树屏障 | CustomKernelEmitter::MaybeInsertGlobalBarrier @0x1321ac20 (§3) | SC Mosaic 每核窗口(mlir::sparse_core::MemorySpaceAttr::get(ctx, 14) — SC MLIR 枚举,不是 jellyfish MemorySpace;AllocateAtOffsetOp); 不是 GetGlobalBarrierSyncFlagNumber | TC 音序器(马赛克)tpu.sem_signal/tpu.sem_wait in scf.for |
| (b) | SC 每个集体全局屏障 | EmitScsBarrier(type1) / EmitAllToAllBarrierStart(type1) → EmitGlobalBarrier @0x13352820 | GetSyncFlagForBarrierId(reserved id) = id + SC_base(SC 屏障块) | SC 定序器 sc_tpu.sync_add SC 内核树 |
| (c) | TC LLO 保留全局插槽 | net_util::GetBarrierSyncFlag(type1) @0x1c69ad00; BarrierCoresTree 等 (§1) | GetGlobalBarrierSyncFlagNumber() = base + count + 4(TC屏障块) | TC 定序器 Vsync* / net_util 树屏障 |
这三者存在于三个数字空间中:(a) SparseCore Mosaic 每核窗口(mlir::sparse_core::MemorySpace 值 14 — SC MLIR 枚举,与水母 MemorySpace 枚举不同,其中 14 = sparse_core_sequencer_smem); (b) SC 屏障块; (c) TC 屏障块 [base, base+count],GLOBAL 插槽位于 +count+4。 (a)和(b)是SparseCore; (c) 是 TensorCore。 GetGlobalBarrierSyncFlagNumber 仅属于 TC 引擎 — 这正是 SparseCore MaybeInsertGlobalBarrier 从不调用它的原因。源 (c) 不是 SC 树屏障 (a):它们是不同的 Target/SparseCoreTarget 字段和不同的定序器。
3. MaybeInsertGlobalBarrier @0x1321ac20 — 插入门
CustomKernelEmitter::MaybeInsertGlobalBarrier 是 SparseCore Mosaic 入口点,决定是否自定义调用函数被赋予函数级全局屏障,并且 - 如果是 - 将其插入到 SC 每核窗口中。它是一个门,而不是 SFLAG 编号源:它读取 CustomCallConfig 标志和 BarrierConfig.type,运行三个合法性 RetCheck,然后遍历 func 的操作以在适当的核心类型上实现屏障。它不计算 GetGlobalBarrierSyncFlagNumber。
3.1 签名和输入
// xla::tpu::sparse_core::CustomKernelEmitter::MaybeInsertGlobalBarrier(
// mlir::ModuleOp module, CustomCallConfig const* cfg, BarrierConfig const* bc) // 0x1321ac20
```text
反编译显示`a1` =模块句柄,`a2` =模块上的遍历迭代器,`a3` = `CustomCallConfig*`,`a4` = `BarrierConfig*`(可能为空)。门从 `CustomCallConfig` (`a3`) 中读取三项内容,从 `BarrierConfig` (`a4`) 中读取一项内容:
| 反编译读取 | 含义(归因于使用 + RetCheck 字符串) |
|---|---|
| `v4 = cfg[+0x10]` 标志双字;位 `0x200` | *has-communication* 字节的存在防护 |
| `v5 = cfg[+0x90]`(如果位 `0x200` 则只读) | **has-communication**标志(自定义调用通信) |
| `v4` 位 `0x2000` | *skip-device-barrier* 字节的存在防护 |
| `v6 = cfg[+0x94]`(如果位 `0x2000` 则只读) | **skip_device_barrier** 标志 |
| `v4` 位 `0x40` | **自定义屏障请求**标志(附有 `BarrierConfig`) |
| `v7 = (bc->type [a4+0x20] == 3)` | 附加屏障为 `CUSTOM(3)` |
### 3.2 三个合法性门(字节精确)
主体解析四个谓词,然后保护三个错误路径,每个路径都有一个锚定到 `custom_kernel_emitter.cc` 的 `absl::Status` `MakeErrorImpl<3>` (`kInvalidArgument`):
```c
result = 1; // OK / kOk by default
// GATE 1 — a barrier was requested for a non-communicating custom call.
if ((flags & 0x40) && !has_communication)
return Error("Custom barrier requested for non-communicating custom call."); // :3560
// GATE 2 — communication needs a global barrier, but the compiler couldn't allocate a
// dedicated SFLAG *and* Mosaic isn't allowed to fall back to a device barrier.
// reached only when (flags & 0x40) is set, has_communication is true,
// the attached barrier is NOT CUSTOM(3) (v7 == false), and skip_device_barrier (v6) is set:
if ((flags & 0x40)) {
if (bc->type == 3 /*CUSTOM*/) return result; // dedicated barrier already allocated → no insert
if (skip_device_barrier)
return Error("The compiler failed to allocate a barrier semaphore and Mosaic "
"wasn't allowed to perform a global barrier due to skip_device_barrier."); // :3572
} else if (skip_device_barrier) {
return result; // no barrier requested + skip → nothing to do
}
// INSERT — walk the module's ops; pick the core-type variant, materialise the barrier.
v12 = 2 - HasAnyCoreType(walk, &kSparseCoreType, 1); // core-type selector (TC vs SC variant)
ok = mlir::detail::walk<ForwardIterator>(walk, MaybeInsertGlobalBarrier::$_0(FuncOp), &state, /*WalkOrder=*/1);
// GATE 3 — the walk found no func it could attach a barrier to.
if (!ok) return Error("Requested barrier for unsupported core type"); // :3681
return result; // OK重新实现者的语义:
- 仅当自定义调用进行通信(
has_communication)并且明确请求屏障(标志0x40)而没有可用的专用CUSTOM(3)配置时,或者到达失败插入路径时,才会插入全局屏障。CUSTOM(3)配置意味着编译器已经分配了每个键的 SFLAG(通过着色生成器),因此MaybeInsertGlobalBarrier返回 OK,而不插入函数级全局 SFLAG。 skip_device_barrier是 逃生舱口:如果 Mosaic 被告知不要发出设备范围的屏障,并且没有分配专用信号量,则门 编译失败(GATE 2),而不是默默地丢弃集合点 - 避免死锁的硬错误。- 实际的屏障物化是
walk回调MaybeInsertGlobalBarrier::$_0(FuncOp访问者):它在 SC 每核窗口(§2 中的源 (a))上构建AllocateAtOffsetOp(MemorySpace::sflag)+scf.for(tpu.sem_signal/tpu.sem_wait)树,由v12 = 2 − HasAnyCoreType(...)。这不是**GetGlobalBarrierSyncFlagNumber— SFLAG 偏移量来自 Mosaic 每核内存预留,而不是 TCTarget+0x8c0块。树协议本身位于 树屏障/vSync 上。
GOTCHA — 三个
CustomCallConfig字段偏移(+0x10标志、+0x90has-communication、+0x94skip_device_barrier)和位掩码(0x200/0x2000/0x40)是来自反编译读取的字节确认;字段 names(has_communication、skip_device_barrier、custom_barrier_requested)源自 RetCheck 字符串("non-communicating custom call"、"due to skip_device_barrier"),而不是来自原始描述符。所有三个门的行为均已确认。注意 — 行号。 三个错误站点是
custom_kernel_emitter.cc:3560、:3572、:3681。BarrierConfig.type == 3读取确认唯一短路全局插入的屏障类型是CUSTOM(3);附加到通信自定义调用的GLOBAL(1)/REPLICA(2)仍采用插入路径。这些与 概述 §3.3 中总结的降低门相匹配。
4. REPLICA(2)路径全球屏障份额
REPLICA(2) 是 TensorCore-only 屏障类型。它不是全局插槽 - 它像 CUSTOM(3) 一样映射到 base + id - 但它与 GLOBAL 屏障一样使用相同的 net_util::GetBarrierSyncFlag 映射器(第 1.2 节)和相同的 BarrierCoresTree 执行器,区别仅在于它选择了哪个 TreeBarrierType(以及哪个对等集)。这就是为什么全局屏障窗口和 REPLICA 路径被记录在一起:它们共享映射器和树屏障引擎;它们仅在对等集(所有核心与副本组对等体)和 SFLAG 插槽(+count+4 与 base+id)处出现分歧。 生成 REPLICA 配置的分类位于 推断屏障配置 上; 复制品屏障 上的完整 REPLICA 降低。本节记录共享路径。
4.1 制作人 — DetermineBarrierConfigForKey @0x109c6fa0
TensorCoreBarrierAssignment::DetermineBarrierConfigForKey(key, config, has_conflict) 构建 BarrierConfig。字节精确决策树:
// 0x109c6fa0
BarrierConfig DetermineBarrierConfigForKey(TensorCoreBarrierKey key, HloModuleConfig config, bool has_conflict) {
BarrierConfig bc{}; // ctor(0)
bool beneficial = IsGlobalBarrierBeneficial(key, config); // 0x109c6ee0
if (has_conflict || beneficial) { // → GLOBAL(1)
bc.type = 1; bc.id = -1; // movl $1,+0x20 ; movq -1,+0x18
} else if (key[+0x10] /*group begin*/ == key[+0x20] - 1 /*group end−1*/) { // single replica group
if (config[+0x50] /*partition flag*/ != 1) { // → REPLICA(2)
bc.type = 2; bc.id = key[+0x10]; // shared key id
} else { // → GLOBAL(1) (partition-scoped singleton)
bc.type = 1; bc.id = -1;
}
} else { // → CUSTOM(3)
bc.type = 3; bc.id = <fresh via __try_key_extraction_impl @0x109cbd60>;
}
bc.hasbits |= 3; // type + id present (orb $3, +0x10)
return bc;
}
```text
`IsGlobalBarrierBeneficial` @`0x109c6ee0` 对于**单一维度**返回 true:由 `key[+0x51]` 门控(ICI 路由已知标志 - 当清除时,它会在 `VLOG`“由于未知 ICI 路由限制而跳过全局屏障优势的评估。”)和`key[+0x50] == 0`(分区标志,此处请重点阅读),然后检查 `+0x170` (replica_count) / `+0x178` (num_partitions) 处的配置派生轴对,并仅当其中一个轴为 `1` **和** `key[+0x10] == 1` (最好由全核全局屏障)。生产者通行证仅写入 `{1, 2, 3}` — **从不写入 `MEGACORE(4)`**。
因此,`REPLICA(2)` 是**每个副本组共享**障碍:*单个*副本组,*不*分区范围(`config[+0x50] != 1`),*无*计划冲突,并且*不*全局受益。它的`id`是共享密钥id(组中的多个集体重用它),满足§1.2中`base + id`映射的`0 <= id < count`。
### 4.2 降低 (TensorCore) — `BarrierCoresTree` 范围仅限于副本组
具有 `BarrierConfig.type == 2` 的 TC 密集集体通过其发射器的 `BarrierStart` 降低(例如 `AllGatherEmitter::BarrierStart` @`0x13809520`)。类型调度 (`r15d == 2`) 使用 `net_util::TreeBarrierType` = `(target_predicate ^ 1)` 调用 `$_3` 闭包 — 即 `REPLICATED(1)` 或 `PARTITIONED(2)`。 SFLAG 本身来自 `GetBarrierSyncFlag(bc)` → `base + id` (§1.2),以及 `$_3` → `net_util::GetRegistryTreeBarrierInfoProvider` @`0x1c6a7480` + `net_util::BarrierCoresTree` @`0x1c6a75c0`:
```text
BarrierConfig{type=2, id} ──GetBarrierSyncFlag──▶ sflag = base + id
──$_3(TreeBarrierType)──▶ BarrierCoresTree
│
GetOrCreateTreeBarrierInfoTable @0x1c6b60e0: ▼
TreeBarrierType 0 ALL_CORES → variant 0x23 (kAllCoresTreeBarrierInfoTable @0xb433290)
TreeBarrierType 1 REPLICATED → variant 0x2a (kReplicatedCoresTreeBarrierInfoTable @0xb4332c0)
TreeBarrierType 2 PARTITIONED → variant 0x2b (kPartitionedCoresTreeBarrierInfoTable@0xb4332f0)
│
BarrierWithinReplicaGroupStartImpl @0x1c698080: ▼
GetReplicaGroupCoreInfo → this core's group peers (from the InfoTable)
Pneg + Predicated → gate participation
for each peer: VsyncAddRemote(sflag, peer) → signal the peer's barrier sflag
BarrierWithinReplicaGroupDone @0x1c6984e0 → waitGLOBAL 屏障在所有核心上采用与 TreeBarrierType = ALL_CORES(0) 相同的 BarrierCoresTree 路径; REPLICA 将对等点集缩小到当前核心的副本组。执行器操作是 VsyncAddRemote @0x1d522f40 — 向每个对等点发送 SFLAG 信号,然后等待 — SparseCore sc_tpu.sync_add (树屏障/vSync) 的 TC 模拟。
BarrierWithinReplicaGroupStartImpl@0x1c698080:反编译显示GetReplicaGroupCoreInfo(解析组对等体),Pneg@0x1d5208e0+Predicated@0x1d520f00(参与门)和VsyncAddRemote(对等信号)。对等集是当前核心的副本组,而不是所有核心。
4.3 成员编码 — 副本组 InfoTable
副本组成员资格是预先计算的 int 成员资格表,而不是位掩码或每环常量文字切片。 net_util::CreateReplicaInfoTable(absl::Span<xla::ReplicaGroup const>, replica_count, partition_count, …) @0x1c69b660 → CreateStaticReplicaInfoTable @0x1c69b780 将 HLO 集合体的 replica_groups 属性展平为由 xla::Literal R1 int 数组支持的 xla::InfoTable (LiteralUtil::CreateR1<int> @0x10aa05e0)。 GetReplicaGroupCoreInfo 以当前核心的序号读取此表以恢复其组对等 ID。 RegisterTreeBarrierInfoTables @0x1c6a8620 每个程序将 ALL/REPLICATED/PARTITIONED 表预注册到 ProgramSharedRegistry 中一次; GetRegistryTreeBarrierInfoProvider 在发出时获取它们(通过 GetReplicaGroupCoreInfoCache 缓存)。
4.4 为什么 REPLICA(2) 在 SparseCore 上永远不会降低 - 以及名称陷阱
两个 SparseCore 自定义内核屏障入口点 RetCheck 类型 2:
EmitScsBarrier@0x13352500:仅限==1 GLOBAL/==3 CUSTOM;否则重新检查。EmitAllToAllBarrierStart@0x133500e0:仅限==1 GLOBAL/==3 CUSTOM; elseRetCheckFailSlowPath(offload_a2a_util.cc:124)"backend_config.barrier_config().barrier_type() == jellyfish::BarrierType::GLOBAL",消息**“SparseCore 上的所有集合仅支持自定义和全局屏障”**。
GOTCHA —
EmitReplicaGroupCustomBarrierStart名称陷阱。 SparseCore 函数字面名为EmitReplicaGroupCustomBarrierStart@0x13353620是 SC A2ACUSTOM(3)屏障(和显式 id 路径)的降低,对于BarrierType::REPLICA不是。它向组中的每个成员发出一个谓词sc_tpu.sync_add,该组的成员资格位于传递的BufferOffset处的 SMEM 缓冲区中,这与 TCREPLICA(2)不同,TCREPLICA(2)的成员资格是InfoTable文字(第 4.3 节)。在 SparseCore 上,根本没有**BarrierType-REPLICA(2)降低;嵌入集合仅使用GLOBAL(1)或CUSTOM(3)。REPLICA(2)是 TensorCore 密集集合势垒类型独有。
EmitAllToAllBarrierStart@0x133500e0:RetCheck 字符串和消息逐字存在于barrier_type调度的else臂的反编译中 — REPLICA(2) 在 SparseCore 上被拒绝。
5. 验证说明
libtpu.sov0.0.40 中的字节精确:
GetGlobalBarrierSyncFlagNumber@0x1d60f420:this[561] + this[560] + 4=base + count + 4— 准确。net_util::GetBarrierSyncFlag@0x1c69ad00:type==1→target()->GetGlobalBarrierSyncFlagNumber()→SflagImmPtr("global barrier sync flag");type==0→ 检查失败(net_util.cc:2065);否则 → 检查id < target[0x8c4](:2070) →id + target[0x8c0]→SflagImmPtr("barrier sync flag number")— 准确,偏移量0x8c0/0x8c4(=2240/2244) 已确认。MaybeInsertGlobalBarrier@0x1321ac20:从cfg[+0x10]读取的标志(位0x200/0x2000/0x40),cfg[+0x90]/cfg[+0x94]、bc->type [+0x20] == 3;三个错误位点custom_kernel_emitter.cc:3560/:3572/:3681; 身体任何地方都不能调用GetGlobalBarrierSyncFlagNumber;通过mlir::detail::walk(MaybeInsertGlobalBarrier::$_0)和v12 = 2 − HasAnyCoreType(...)插入 — 准确。DetermineBarrierConfigForKey@0x109c6fa0:if (has_conflict || IsGlobalBarrierBeneficial)→type=1, id=-1;否则if (key[+0x10] == key[+0x20]−1)然后config[+0x50]!=1→type=2, id=key[+0x10]否则type=1,id=-1;否则 →type=3, id=fresh;hasbits |= 3— 精确(分区标志读取反汇编为cmpb $0x1,0x50(%r14),其中%r14=HloModuleConfig,第二个参数 — config,而不是密钥); 没有movl $4。BarrierCoresTree@0x1c6a75c0:调用GetGlobalBarrierSyncFlagNumber→SflagImmPtr("global barrier sync flag")— 在正文中确认。BarrierWithinReplicaGroupStartImpl@0x1c698080:GetReplicaGroupCoreInfo+Pneg/Predicated+VsyncAddRemote— 已确认。EmitAllToAllBarrierStart@0x133500e0:REPLICA(2) RetCheck(offload_a2a_util.cc:124,“SparseCore 上的所有集合仅支持自定义和全局屏障”)- 已确认。[HIGH]
CustomCallConfig字段名称(has_communication@+0x90、skip_device_barrier@+0x94、custom_barrier_requested位0x40)和TensorCoreBarrierKey字段标识(+0x10/+0x20组范围;+0x50分区标志和+0x51ICI 路由已知防护,由IsGlobalBarrierBeneficial读取)— 字节确认的偏移量,来自 RetCheck 字符串和配置读取的名称,而不是来自结构体描述符。注意:DetermineBarrierConfigForKey内的 REPLICA-vs-GLOBAL 分区测试从HloModuleConfig(%r14) 读取不同+0x50字节,而不是从密钥读取。[LOW] 每个
(codename, deployment){base, count}整数的文字 (Target+0x8c0/+0x8c4) 是从嵌入式芯片配置内存文件 blob 运行时解析的,并且不是静态提取的;窗口几何(count = |CR_TC| − 5,GLOBAL @+count+4)已确认。请参阅 按代号编译器保留。 net_utilInfoTable在线索引(GetReplicaGroupCoreInfo如何映射核心序数→其在扁平 R1 int 文字中的对等集)未完全反汇编 - 被证明是replica_count × partition_count键控的 int 表;每个条目的含义为“低”。
交叉引用
屏障算法(本节)
- 屏障和同步标志 — 剖面图 — 子系统映射:
BarrierType枚举,生产者→标准化器→降低流量,每代 SFLAG 内存映射 - 屏障到 SFLAG 的绑定 —
base+count+4/base+idSFLAG 数字公式和 TC 保留时隙映射(本页使用的公式) - 推断屏障配置 — 生成
GLOBAL/REPLICA/CUSTOM配置的分类(提供窗口 + REPLICA 路径的标准化器) - 复制品屏障 — 完全副本组内树屏障降低 (
REPLICA(2)) - 按代号编译器保留 —
(codename, deployment){base, count}SFLAG 范围整数的文字 - 树屏障/vSync — GLOBAL 和 REPLICA 均启动的 signal-all-then-wait 树协议
- TensorCore 屏障 — TC 基底信号/等待屏障和着色选择的
CUSTOMid - 屏障着色 — 为
DetermineBarrierConfigForKey的has_conflict提供支持的干涉图引擎 - 专用同步标志 — 来源保留块的
compiler_reserved范围
同级子系统
- SFLAG 同步标志层 — 每个势垒都建立在 SFLAG 原子计数器基板上
- 集合通信 — 消耗全球/复制壁垒的密集集体
- 返回索引