SpecialPurposeSyncFlags — 芯片配置 SFLAG 保留消息、其 FromProto 接收器和 GetSpecialPurposeSyncFlags 访问器
二进制:
extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(构建 ID89edbbe81c5b328a958fe628a9f2207d,构建libtpu_lts_20260413_b_RC00;.textVMA == 文件偏移量0xe63c000、.rodataVMA == 文件偏移量0x84a0000)。 状态: 重新实现级 · 证据等级: 已确认(字节锚定) —GetSpecialPurposeSyncFlags访问器、TpuChipConfig::FromProto元素构建、0x40 字节运行时元素布局、EnumMap::Clear标量持久性和Target::Init/SparseCoreTarget::Init结构接收器都是字节精确的(+core<<6、& 0x100000000存在门、size − 5)。每代 SFLAG 整数的文字是嵌入式内存文件依赖项(低 — 请参阅 按代号编译器保留)。 · 第 XIII 部分 — Pod 上的集体和障碍 / SFLAG 和障碍 · 返回索引
摘要
TPU 上的每个屏障都是一个保留的 同步标志 (SFLAG) 数字,并且屏障可能采用的数字不是硬编码的 - 它们在芯片配置中携带,每种核心类型一组。载体是原始子消息 SpecialPurposeSyncFlags,嵌入为 TpuChipConfigProto 的重复字段 13。每个实例将 compiler_reserved 重复 int32 范围(每个 id 屏障窗口)与四个命名标量 SFLAG 编号(sequencer_overlay、tile_overlay、global_barrier_sflag、local_barrier_sflag)配对。 屏障到 SFLAG 的绑定上实时消耗compiler_reserved的通用SFLAG数字公式;每个 (codename, deployment) 整数的文字存在于 按代号编译器保留 上。 此页面拥有解析和访问路径:将原型放入 EnumMap 元素的 TpuChipConfig::FromProto 运行时接收器、检索它的 GetSpecialPurposeSyncFlags(coreType) 访问器(chip+0x2a0 + (core<<6),由 chip+0x360 存在位掩码门控)、四个命名标量(每个单个 SFLAG 索引(不是位掩码)包含存在布尔值(EnumMap::Clear),以及按核心类型对集合进行键控的 EnumMap<TpuCoreType, SpecialPurposeSyncFlags, 3>。
重新实现,合约为:
- 原始载体:
TpuChipConfigProto.special_purpose_sync_flags(字段 13,重复SpecialPurposeSyncFlags),每个TpuCoreType一个元素。每个元素都有core_type(f1)、compiler_reserved(f3,重复的 int32) 和四个标量 SFLAG 编号sequencer_overlay/tile_overlay/global_barrier_sflag/local_barrier_sflag(f4–f7)。 - FromProto 接收器:
TpuChipConfig::FromProto@0x20aea100将compiler_reserved堆复制到vector<int32>并将四个标量逐字(低 32 位 = 数字,位 32 = 存在)存储到 0x40 字节中EnumMap元素,然后设置该核心的 EnumMap 存在位。标量不会折叠到compiler_reserved中 - 它们保留在元素填充中。 - 访问器:
GetSpecialPurposeSyncFlags(core)@0x20afcf40如果每核存在位 (chip+0x360) 清零,则返回NULL,如果core >= 3,则返回ud1陷阱,否则返回chip + 0x2a0 + (core<<6)(元素步幅0x40)。 TensorCore 条目是强制性的:如果不存在,Target::Init将通过DieBecauseNull消亡。 - 覆盖语义: 每个命名标量都是一个单个 SFLAG 编号,存在门控,按需复制到
Target/SparseCoreTarget字段中。命名标量路径是 SparseCore-only;在 TC 上仅消耗sequencer_overlay(→Target+0x534)。四个标量在EnumMap::Clear中保留下来(仅释放compiler_reserved向量)。
| 原型载体 | TpuChipConfigProto.special_purpose_sync_flags(字段 13,重复 SpecialPurposeSyncFlags) |
| 原始元素字段 | core_type f1 @msg+0x2c; compiler_reserved f3(计数@+0x1c,数据@+0x18/+0x20); sequencer_overlay f4 @+0x30; tile_overlay f5 @+0x34; global_barrier_sflag f6 @+0x38; local_barrier_sflag f7 @+0x3c |
| FromProto 水槽 | TpuChipConfig::FromProto @0x20aea100(special_Purpose_sync_flags 循环) |
| 运行时容器 | EnumMap<TpuCoreType, SpecialPurposeSyncFlags, 3> @TpuChipConfig+0x2a0,跨步 0x40,存在位掩码 @+0x360 |
| 配件 | GetSpecialPurposeSyncFlags(core) @0x20afcf40 → chip + 0x2a0 + (core<<6) |
| EnumMap 拆解 | EnumMap<…SpecialPurposeSyncFlags,3>::Clear @0x20b08200(仅释放 compiler_reserved 矢量) |
| TC结构水槽 | Target::Init @0x1d60fc20 → Target+0x8c0/+0x8c4(cr 基数/计数−5),+0x534(sequencer_overlay) |
| SC结构水槽 | SparseCoreTarget::Init @0x1d612b20 → +0x1d0/+0x1d4(cr 基数/计数,无 −5), +0x1e8/+0x200/+0x204/+0x208(四个标量) |
| 标量语义 | 单个 SFLAG 索引,不是位掩码; value@bits[31:0]、present@bit[32] |
1. 原型载体 — SpecialPurposeSyncFlags
SpecialPurposeSyncFlags是TpuChipConfigProto的子消息,作为重复字段13 special_purpose_sync_flags携带。芯片配置为每个 TpuCoreType 携带一个实例(kTensorCore=0、kSparseCore=1、kBarnaCore=2)。每个实例将为编译器保留的 SFLAG 编号的“范围”与覆盖/屏障降低所使用的四个“单独”命名的 SFLAG 编号捆绑在一起。
生成的 C++ 消息结构偏移量(从生成的 _InternalSerialize @0x20b0f040 恢复,它是权威布局见证 — WriteInt32<ILi4>(+0x30) … <ILi7>(+0x3c))是:
| 原型场 | 名称 | 型 | 消息结构偏移 | 角色 |
|---|---|---|---|---|
| f1 | core_type | 枚举 TpuCoreTypeProto | @+0x2c | 选择该元素描述的核心类型 |
| f3 | compiler_reserved | 重复 int32 | 计数 @+0x1c,数据 @+0x18(内联)/@+0x20(堆) | 每个 id 屏障 SFLAG 窗口(升序连续) |
| f4 | sequencer_overlay | int32 | @+0x30 | 覆盖保留的 SFLAG 号(单个索引) |
| f5 | tile_overlay | int32 | @+0x34 | 平铺覆盖 SFLAG 编号(SC;单个索引) |
| f6 | global_barrier_sflag | int32 | @+0x38 | SC全局屏障SFLAG编号(单一索引) |
| f7 | local_barrier_sflag | int32 | @+0x3c | SC本地屏障SFLAG编号(单索引) |
注意 — hasbits 字位于
@+0x10。core_type槽是运行时消息结构中的+0x2c— 与+0x1c不同,+0x1c是原始字段编号/描述符列表偏移量,而不是运行时结构偏移量。compiler_reservedfield-3 范围以及从base/count(base+count+4全局、base+countmegacore、base+id每键)构建的通用 SFLAG 数字公式记录在 屏障到 SFLAG 的绑定 上;每个(codename, deployment)文字整数位于 按代号编译器保留 上。
2. FromProto 水槽 — TpuChipConfig::FromProto
TpuChipConfig::FromProto @0x20aea100 带有专用的 special_purpose_sync_flags 循环,该循环根据 SpecialPurposeSyncFlags 原型元素解码核心类型,堆复制 compiler_reserved 范围,捕获四个标量及其存在位,并写入0x40 字节 EnumMap 元素。该循环迭代重复字段 13(从 @proto+0x98 开始,计数 @proto+0xa0)。字节精确的主体:
// TpuChipConfig::FromProto @0x20aea100 — special_purpose_sync_flags loop (one element)
for (each SpecialPurposeSyncFlags msg in proto.special_purpose_sync_flags) { // field 13
core = TpuCoreTypeFromProto(*(int*)(msg + 0x2c)); // 0=TC, 1=SC, 2=BC
cr_count = *(int*)(msg + 0x1c); // compiler_reserved size
cr_data = (hasbit on msg+0x18) ? *(int**)(msg + 0x20) // heap repeated field
: (int*)(msg + 0x18); // inline
// heap copy of the compiler_reserved range
v.data = (int*)_Znwm(cr_count * 4);
memcpy(v.data, cr_data, cr_count * 4);
v.size = v.cap = cr_count;
// the four scalars, each packed (value | present<<32)
seq_ov = (long)*(int*)(msg + 0x30) | (seq_ov > 0 ? 0x100000000 : 0); // f4
tile_ov = (long)*(int*)(msg + 0x34) | (tile_ov > 0 ? 0x100000000 : 0); // f5
glob_bar = (long)*(int*)(msg + 0x38) | (glob_bar > 0 ? 0x100000000 : 0); // f6
local_bar= (long)*(int*)(msg + 0x3c) | (local_bar> 0 ? 0x100000000 : 0); // f7
elem = chip + 0x2a0 + (core << 6); // EnumMap element, 0x40-byte stride
*(int*) (elem + 0x00) = core; // element key / runtime core marker
*(int**) (elem + 0x08) = v.data; // compiler_reserved vector data ptr
*(long*) (elem + 0x10) = v.size; // compiler_reserved size
*(long*) (elem + 0x18) = v.cap; // compiler_reserved cap (== size)
*(int*) (elem + 0x20) = tile_ov_value; *(bool*)(elem + 0x24) = tile_ov_present;
*(int*) (elem + 0x28) = seq_ov_value; *(bool*)(elem + 0x2c) = seq_ov_present;
*(int*) (elem + 0x30) = glob_bar_value; *(bool*)(elem + 0x34) = glob_bar_present;
*(int*) (elem + 0x38) = local_bar_value; *(bool*)(elem + 0x3c) = local_bar_present;
set_enummap_presence_bit(chip + 0x360, core); // bts core, *(chip+0x360)
}
```text
对于重新实现者来说,有两个属性很重要:
- **标量逐字存储。** 作者的 `>>8` / `<<8` 拆分 + 低字节 `movzbl` (在原始反汇编中可见)是寄存器分配工件:它重建精确的原始值,同时在打包 qword 的位 32 中单独携带存在 bool。存在 bool 计算为 `setg` (`value > 0`),因此零或负值读取为不存在。
- **元素排序不是原始顺序。** 请注意,元素首先存储 `tile_overlay` (`+0x20`),然后存储 `sequencer_overlay` (`+0x28`),反转原始字段顺序 (f4 `sequencer_overlay`, f5 `tile_overlay`)。结构体接收器 (§5) 读取元素偏移量,而不是原始偏移量 — `Target::Init` 读取 `sequencer_overlay` 的元素 `+0x28`。
> **已确认(反编译)—** 在 `FromProto` 的 `special_purpose_sync_flags` 循环中,元素基础是 `v1047 << 6` (= `core * 0x40`),并且每个元素逐字重建四个标量 (`>>8` / `<<8 | low-byte` 寄存器拆分),存在布尔值单独存储:`sequencer_overlay` 存在被携带为 `v706 = v705 + 0x100000000`(= `*(int*)(msg+0x30)`,位 32 = `value > 0`); `tile_overlay`/`global_barrier`/`local_barrier` 存在是在元素处写入的字节 `setg` 标志 `v710`/`v711`/`v714` (= `*(int*)(msg+0x34/0x38/0x3c) > 0`) `+0x24`/`+0x34`/`+0x3c`。读者(`Target::Init` / `SparseCoreTarget::Init`)在打包的qword上测试`& 0x100000000`。重复字段副本为 `operator new(4*count)` + `memcpy`。这与原型→元素→结构链完全匹配。
---
## 3. 运行时容器 — `EnumMap<TpuCoreType, SpecialPurposeSyncFlags, 3>`
三个每核元件位于固定容量 `EnumMap<TpuCoreType, SpecialPurposeSyncFlags, 3>` 中,该固定容量 `EnumMap<TpuCoreType, SpecialPurposeSyncFlags, 3>` 直接嵌入在 `TpuChipConfig` 内,偏移量为 `+0x2a0`。该映射由 `TpuCoreType`(枚举值*是*元素索引)作为键控,在 `+0x360` 处具有单独的每核存在位掩码。它是一个固定数组,而不是哈希映射:`+0x2a0`、`+0x2e0`、`+0x320` 处的三个 0x40 字节槽。
### 3.1 元素布局(0x40 字节)
| 元素偏移 | 内容 | 源码 |
|---|---|---|
| `+0x00` | 元素密钥/运行时核心 (0/1/2) | `core` |
| `+0x08` | `compiler_reserved` 矢量数据 ptr | `_Znwm` 结果 |
| `+0x10` | `compiler_reserved` 尺寸 | `cr_count` |
| `+0x18` | `compiler_reserved` 帽(==尺寸) | `cr_count` |
| `+0x20` | `tile_overlay` (int32) | 原型 f5 `@msg+0x34` |
| `+0x24` | `tile_overlay` 当前(布尔) | `setg (value > 0)` |
| `+0x28` | `sequencer_overlay` (int32) | 原型 f4 `@msg+0x30` |
| `+0x2c` | `sequencer_overlay` 当前(布尔) | bit-32 包装 |
| `+0x30` | `global_barrier_sflag` (int32) | 原型 f6 `@msg+0x38` |
| `+0x34` | `global_barrier_sflag` 当前(布尔) | `setg` |
| `+0x38` | `local_barrier_sflag` (int32) | 原型 f7 `@msg+0x3c` |
| `+0x3c` | `local_barrier_sflag` 当前(布尔) | `setg` |
### 3.2 拆解 — `EnumMap::Clear` 仅释放向量
`EnumMap<TpuCoreType, SpecialPurposeSyncFlags, 3>::Clear` @`0x20b08200` 遍历三个元素(`+0x0`/`+0x40`/`+0x80`),并且对于每个存在位(映射中的 `+0xc0`)被设置的元素,释放`compiler_reserved` 向量(`begin@+0x8`、`cap@+0x18 << 2` 字节)并将 `+0x10` 处的大小归零。 **它永远不会触及 `+0x20..+0x3c`。** 结果:四个命名标量保留在元素填充中 - 它们存储在 `FromProto` 时间并由 `Target::Init` / `SparseCoreTarget::Init` 按需读取,而不是被消耗和丢弃。
> **注意 —** 这就是为什么四个标量被描述为“在元素中”而不是“在解析的结果结构中”。 `compiler_reserved` 向量是元素拥有的唯一堆分配;其他所有内容都是 0x40 字节槽中的普通旧数据。
---
## 4. 访问器 — `GetSpecialPurposeSyncFlags(coreType)`
`GetSpecialPurposeSyncFlags(core)` @`0x20afcf40` 是 `SpecialPurposeSyncFlags` 元素的单个检索路径。它是 `chip+0x2a0` 上 `EnumMap` 上的存在门控、边界检查地址计算:
```c
// TpuChipConfig::GetSpecialPurposeSyncFlags(TpuCoreType core) @0x20afcf40
SpecialPurposeSyncFlags* GetSpecialPurposeSyncFlags(TpuChipConfig* chip, TpuCoreType core) {
uint64_t mask = *(uint64_t*)(chip + 0x360); // per-core presence bitmask
if (!_bittest64(&mask, core)) return NULL; // bt core, mask; jae → NULL
if ((unsigned)core >= 3) ud1(); // CHECK core ∈ {0,1,2}
return chip + 0x2a0 + ((uint64_t)core << 6); // element `core`, 0x40-byte stride
}重新实施者必须履行的合同:
- 首先检查存在性,然后检查边界。 如果芯片配置没有为
core携带SpecialPurposeSyncFlags,则访问器在core < 3检查之前*返回NULL。不检查NULL返回值的调用者将取消引用空垃圾。 - 索引是
core << 6,而不是+core。 元素步长是0x40(EnumMap 元素大小);索引+0x2a0 + core的重新实现将core=1读入 TensorCore 元素的compiler_reserved指针,将core=2读入其标量填充 —kSparseCore/kBarnaCore是垃圾。 - TensorCore 条目是强制性的。
Target::Init调用kTensorCore的访问器,并在NULL上通过DieBecauseNull终止,字符串为"chip_config.GetSpecialPurposeSyncFlags( ::tpu::TpuCoreType::kTensorCore)"。每个有效的芯片配置必须携带一个 TC 专用条目。
已确认(反编译)— 访问器主体正是
v2 = *(chip+864); if (!_bittest64(&v2, core)) return 0; if ((unsigned)core >= 3) ud1; return chip + 672 + (core << 6)— 即+0x360位掩码、+0x2a0基址 (672 = 0x2a0)、core << 6步幅。构建中此访问器的六个调用者是Target::Init(×2)、SparseCoreTarget::Init(×2)、TpuPxcDriver::InitializeCores和TpuProfilerControlListener::CanStartProfiler。
该访问器也在 概述 §5.1 上进行了总结;本页为权威推导。
5. 覆盖语义——四个命名标量
四个命名标量(sequencer_overlay、tile_overlay、global_barrier_sflag、local_barrier_sflag)各自是一个单个 SFLAG 编号(SFLAG 内存空间的索引),而不是位掩码。它们覆盖通用 SFLAG 窗口,即它们保留 compiler_reserved 每个 id 范围之外的特定 SFLAG 索引,固定到每代 SFLAG 地址空间的顶部。 FromProto 将它们存储到 EnumMap 元素中后,Target::Init / SparseCoreTarget::Init 将当前的复制到命名的 Target / SparseCoreTarget 字段中,每个字段都由 bit-32 存在测试保护。
5.1 存在门控 qword
每个标量占用一个 8 字节元素 qword:bits[31:0] = SFLAG 编号,bit[32](掩码 0x100000000)= 原始存在布尔值。阅读器测试位 32(test $0x100000000, qword 或 bt $0x20, qword)并仅存储低 32 位(如果存在):
// SparseCoreTarget::Init @0x1d612b20 — scalar store (representative; one of four)
v74 = *(uint64_t*)(elem + 0x30); // global_barrier_sflag (packed)
if (v74 & 0x100000000) // bit-32 presence gate
*(int*)(sparse_core_target + 0x204) = (int)v74; // store low 32 bits = the SFLAG number
```text
### 5.2 结构体接收器和消费者
`Target::Init` 仅将 `sequencer_overlay` 复制到命名 TC 字段中; `SparseCoreTarget::Init` 将所有四个复制到 SC 字段中。 TC `tile_overlay`/`global_barrier_sflag`/`local_barrier_sflag` 标量对于 TC **永远不会读取** — 命名标量屏障/覆盖路径仅适用于 SparseCore。 (TC global/megacore/all-reduce 障碍来自 `compiler_reserved` 通过 `base+count+{0,2,3,4}` — 请参阅 [屏障到 SFLAG 的绑定](barrier-to-sflag-binding.md)。)
| 标量(原场) | 元件关闭 | 存在门 | TC水槽 | SC水槽 | 消费者 |
|---|---|---|---|---|---|
| `sequencer_overlay` (f4) | `+0x28` | 位 32 | `Target+0x534` | `SparseCoreTarget+0x200` | TC:`GetOverlayReservedSyncFlagNumber` → 覆盖保留的 SFLAG(单个索引)。 SC:**无**(已存储,在此版本中从未读取) |
| `tile_overlay` (f5) | `+0x20` | 位 32 | (未复制) | `SparseCoreTarget+0x1e8` | SC:`overlayer::OverlayProgram` 将其编码为 `SyImm32` MC 立即数;还由 `EmitFinishDescriptorDma`/`EmitEmulatedContinuation` 阅读 |
| `global_barrier_sflag` (f6) | `+0x30` | 位 32 | (未复制) | `SparseCoreTarget+0x204` | SC:`LoweringEmitter::Emit` / `CustomKernelEmitter::MaybeInsertGlobalBarrier`(`mlir::sparse_core::MemorySpaceAttr::get(ctx, 14)` 全局屏障 SFLAG MemRef — SC MLIR 枚举 sflag-band 值 14,**不是**水母 `MemorySpace` 枚举) |
| `local_barrier_sflag` (f7) | `+0x38` | 位 32 | (未复制) | `SparseCoreTarget+0x208` | SC:`lowering_util::ReservedLocalBarrierSflag`(1-elt i32 MemRef、`mlir::sparse_core::MemorySpaceAttr::get(ctx, 5)` — SC MLIR 枚举 sflag-band 值 5,**不是**水母 `MemorySpace`) |
| `compiler_reserved` (f3) | `+0x08`/`+0x10` | (矢量,始终) | `Target+0x8c0`/`+0x8c4`(数量 = 大小 **−5**) | `SparseCoreTarget+0x1d0`/`+0x1d4`(计数 = 大小,**无 −5**) | per-id 屏障窗口 — 参见 [屏障到 SFLAG 的绑定](barrier-to-sflag-binding.md) |
### 5.3 为什么“overlay”是索引,而不是位掩码
`sequencer_overlay` 降落在 `Target+0x534` 并由 `GetOverlayReservedSyncFlagNumber()` @`0x1d617900` (`mov 0x534(rdi), eax; ret`) 返回。它的所有四个使用者都将其视为一个 int SFLAG 数字,切勿对它进行 AND/测试:
- `EmitContinuationTailcall` @`0x12718ca0`:数字 → `SflagImmPtr(int, "overlay reserved sync flag")` → 用作 DMA 完成标志的单个 SFLAG 指针。
- `LinkAndFinishProgram` @`0x10a25a20`:将 `{number → "overlay"}` 插入 `std::map<int, string>`(`{GetGlobalBarrierSyncFlagNumber → "global barrier"}` 旁边)——单个映射键。
- `CodeGenerationHelper::emit_routine<1>` / `<3>` @`0x1409a5a0` / `0x14062da0`:数字 → `linked_hash_map<int, BundleImmediatesMetadata>` 密钥。
每代值遵循 `2^n − 1` 级数 — `254`(0xFE、JF/DF)、`511`(0x1FF、PF/VF/GL)、`4095` (0xFFF, GF) — **不是**因为它是位掩码,而是因为覆盖保留的 SFLAG 被固定到最顶层的可寻址 SFLAG 索引,并且 SFLAG 编号编码宽度每代都会增长(8→9→12 位;gen ISA `SyncFlagCountType`)。 SC `tile_overlay`/`sequencer_overlay` (7167/7157) 同样作为单个 SFLAG 索引,在 MemorySpace::sflag 中具体化为 1 元素 i32 MemRef。
> **低 —** 每代 SFLAG 编号位宽 (8/9/12) 归因于 gen ISA `SyncFlagCountType` 加上 `2^n − 1` 覆盖编号级数;它不会在一个访问器中被读取为单个二进制文字。 *index-not-bitmask* 结论已确认(没有消费者掩盖该值); *宽度*是推断出来的。每个 gen 的文字标量值是嵌入式 memfile 依赖项(请参阅 [按代号编译器保留](per-codename-compiler-reserved.md))。
>
> **QUIRK —** SC `sequencer_overlay`(`SparseCoreTarget+0x200`,值 7157)由 `SparseCoreTarget::Init` *存储*,但在此版本中 `.text` 中的任何地方都没有**读取器** — 它被摄取但未使用。 SC 覆盖层读取为 `tile_overlay` (`+0x1e8`),而不是 `sequencer_overlay`。无法从二进制文件中确定这是一个已退役的字段、一个为下一代提前声明的字段,还是一个标记禁用的路径。重新实现者仍然应该摄取它(原型携带它),但不需要连接消费者。
---
## 6. 完整的芯片配置 → 元素 → 结构体 → 消费者链
从原型到消费者、字节锚定的端到端的完整数据路径:
```text
TpuChipConfigProto.special_purpose_sync_flags[core] (field 13, repeated SpecialPurposeSyncFlags)
│ core_type f1 @+0x2c ; compiler_reserved f3 ; seq_ov f4 ; tile_ov f5 ; glob f6 ; local f7
│
FromProto @0x20aea100 — per element:
│ _Znwm + memcpy(compiler_reserved) ; pack 4 scalars (value | present<<32)
▼
EnumMap<TpuCoreType, SpecialPurposeSyncFlags, 3> @TpuChipConfig+0x2a0 (stride 0x40, bitmask +0x360)
│ element: +0x08/+0x10/+0x18 cr vector ; +0x20/+0x28/+0x30/+0x38 scalars (+presence)
│ Clear @0x20b08200 frees only the cr vector → scalars persist
│
GetSpecialPurposeSyncFlags(core) @0x20afcf40 — presence-gated, bounds-checked, +0x2a0+(core<<6)
│
├── Target::Init @0x1d60fc20 (core=TC, NULL → DieBecauseNull)
│ element +0x10 size / +0x08 data → contiguity-check → Target+0x8c0 base, +0x8c4 count−5
│ element +0x28 sequencer_overlay (if present) → Target+0x534 = GetOverlayReservedSyncFlagNumber
│ → EmitContinuationTailcall / LinkAndFinishProgram / emit_routine<1,3> (single index)
│
├── SparseCoreTarget::Init @0x1d612b20 (core=SC)
│ element +0x10 size / +0x08 data → SparseCoreTarget+0x1d0 base, +0x1d4 count (no −5)
│ +0x20 tile_overlay → +0x1e8 (→ overlayer::OverlayProgram SyImm32)
│ +0x28 sequencer_overlay → +0x200 (stored, NO reader)
│ +0x30 global_barrier_sflag → +0x204 (→ MaybeInsertGlobalBarrier, SC MLIR MemSpace 14)
│ +0x38 local_barrier_sflag → +0x208 (→ ReservedLocalBarrierSflag, SC MLIR MemSpace 5)
│
├── TpuPxcDriver::InitializeCores @0xe806500 (reads only the cr vector +0x08/+0x10)
└── TpuProfilerControlListener::CanStartProfiler @0xf3328c0 (profiler gate)compiler_reserved 雕刻(TC 上的 −5 保留、SC 全范围以及从 base/count 构建的 per-id/global/megacore/all-reduce SFLAG 公式)是 屏障到 SFLAG 的绑定 的主题。此页面停在现场商店;它不会重新推导数字公式。
7. 验证说明
libtpu.sov0.0.40 中的字节精确:
GetSpecialPurposeSyncFlags@0x20afcf40:v2 = *(chip+864);if (!_bittest64(&v2, core)) return 0;if ((unsigned)core >= 3) ud1;return chip + 672 + (core<<6)— 即+0x360位掩码、+0x2a0基础、core<<6步长 — 字节精确。TpuChipConfig::FromProto@0x20aea100:在special_purpose_sync_flags循环中,元素基础为core << 6;四个标量逐字存储(>>8/<<8|low-byte重建),sequencer_overlay存在作为v705 + 0x100000000携带,其他三个作为setg (value > 0)字节在元素+0x24/+0x34/+0x3c;compiler_reserved通过operator new(4*count)+memcpy— 确认元件构建和(值、当前)包装。Target::Init@0x1d60fc20:*((_DWORD*)target + 560) = *base(=Target+0x8c0底座);*((_DWORD*)target + 561) = size − 5(=Target+0x8c4计数);由& 0x100000000在元素+0x28处门控的sequencer_overlay;DieBecauseNull("…GetSpecialPurposeSyncFlags( ::tpu::TpuCoreType::kTensorCore)")对NULL— 准确。SparseCoreTarget::Init@0x1d612b20:+464/+468=+0x1d0/+0x1d4(基数/计数,无−5);四个标量存储+488/+512/+516/+520(=+0x1e8/+0x200/+0x204/+0x208),每个标量存储由& 0x100000000— 准确。[LOW] 每代
compiler_reserved整数的文字和四个标量值(例如sequencer_overlay = 254/511/4095、SCglobal_barrier_sflag = 7156、local_barrier_sflag = 7155)是从嵌入式芯片配置 memfile 二进制 pb blob 运行时解析的,并且不是在此处静态提取的。每代 SFLAG 编号位宽 (8/9/12) 是从2^n − 1覆盖级数 + gen ISASyncFlagCountType推断出来的,而不是作为单个文字读取。 index-not-bitmask 覆盖语义、FromProto 接收器、访问器、EnumMap 布局和结构接收器均已确认字节锚定。
交叉引用
屏障算法(本节)
- 概述 — 障碍子系统图; §5.1总结了
GetSpecialPurposeSyncFlags访问器(本页为权威推导) - 屏障到 SFLAG 的绑定 — 从
compiler_reservedbase/count构建的通用 SFLAG 数字公式(base+count+4全局、base+countmegacore、base+id每键) - 按代号编译器保留 —
(codename, deployment)compiler_reserved整数和标量值的文字(memfile 解析) - 推断屏障配置 — 消耗雕刻 TC
count的钳融合CUSTOM → GLOBAL/REPLICA标准化器 - 全局屏障窗口 —
base+count+4全局 SFLAG 插槽和每核屏障窗口
同级子系统
- SFLAG 同步标志层 — 每个屏障(和覆盖保留)都建立在 SFLAG 原子计数器基板上
- 返回索引