Skip to content

SpecialPurposeSyncFlags — 芯片配置 SFLAG 保留消息、其 FromProto 接收器和 GetSpecialPurposeSyncFlags 访问器

二进制: 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 == 文件偏移量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_overlaytile_overlayglobal_barrier_sflaglocal_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 @0x20aea100compiler_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) @0x20afcf40chip + 0x2a0 + (core<<6)
EnumMap 拆解EnumMap<…SpecialPurposeSyncFlags,3>::Clear @0x20b08200(仅释放 compiler_reserved 矢量)
TC结构水槽Target::Init @0x1d60fc20Target+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

SpecialPurposeSyncFlagsTpuChipConfigProto的子消息,作为重复字段13 special_purpose_sync_flags携带。芯片配置为每个 TpuCoreType 携带一个实例(kTensorCore=0、kSparseCore=1、kBarnaCore=2)。每个实例将为编译器保留的 SFLAG 编号的“范围”与覆盖/屏障降低所使用的四个“单独”命名的 SFLAG 编号捆绑在一起。

生成的 C++ 消息结构偏移量(从生成的 _InternalSerialize @0x20b0f040 恢复,它是权威布局见证 — WriteInt32<ILi4>(+0x30)<ILi7>(+0x3c))是:

原型场名称消息结构偏移角色
f1core_type枚举 TpuCoreTypeProto@+0x2c选择该元素描述的核心类型
f3compiler_reserved重复 int32计数 @+0x1c,数据 @+0x18(内联)/@+0x20(堆)每个 id 屏障 SFLAG 窗口(升序连续)
f4sequencer_overlayint32@+0x30覆盖保留的 SFLAG 号(单个索引)
f5tile_overlayint32@+0x34平铺覆盖 SFLAG 编号(SC;单个索引)
f6global_barrier_sflagint32@+0x38SC全局屏障SFLAG编号(单一索引)
f7local_barrier_sflagint32@+0x3cSC本地屏障SFLAG编号(单索引)

注意 — hasbits 字位于 @+0x10core_type 槽是运行时消息结构中的 +0x2c — 与 +0x1c 不同,+0x1c 是原始字段编号/描述符列表偏移量,而不是运行时结构偏移量。 compiler_reserved field-3 范围以及从 base/count(base+count+4 全局、base+count megacore、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)。字节精确的主体:

c
// 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::InitializeCoresTpuProfilerControlListener::CanStartProfiler

该访问器也在 概述 §5.1 上进行了总结;本页为权威推导。


5. 覆盖语义——四个命名标量

四个命名标量(sequencer_overlaytile_overlayglobal_barrier_sflaglocal_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, qwordbt $0x20, qword)并仅存储低 32 位(如果存在):

c
// 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 编号编码宽度每代都会增长(8912 位;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.so v0.0.40 中的字节精确:

  • GetSpecialPurposeSyncFlags @0x20afcf40v2 = *(chip+864)if (!_bittest64(&v2, core)) return 0if ((unsigned)core >= 3) ud1return 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、SC global_barrier_sflag = 7156local_barrier_sflag = 7155)是从嵌入式芯片配置 memfile 二进制 pb blob 运行时解析的,并且不是在此处静态提取的。每代 SFLAG 编号位宽 (8/9/12) 是从 2^n − 1 覆盖级数 + gen ISA SyncFlagCountType 推断出来的,而不是作为单个文字读取。 index-not-bitmask 覆盖语义、FromProto 接收器、访问器、EnumMap 布局和结构接收器均已确认字节锚定。


交叉引用

屏障算法(本节)

  • 概述 — 障碍子系统图; §5.1总结了GetSpecialPurposeSyncFlags访问器(本页为权威推导)
  • 屏障到 SFLAG 的绑定 — 从 compiler_reserved base/count 构建的通用 SFLAG 数字公式(base+count+4 全局、base+count megacore、base+id 每键)
  • 按代号编译器保留(codename, deployment) compiler_reserved 整数和标量值的文字(memfile 解析)
  • 推断屏障配置 — 消耗雕刻 TC count 的钳融合 CUSTOM → GLOBAL/REPLICA 标准化器
  • 全局屏障窗口base+count+4 全局 SFLAG 插槽和每核屏障窗口

同级子系统