BCS 32 字节捆绑包
此页面上的所有地址、偏移量和位位置均适用于
libtpu-0.0.40-cp314轮中的libtpu.so(内部版本libtpu_lts_20260413_b_RC00、内部版本89edbbe81c5b328a958fe628a9f2207d)。 ELF 没有被剥离;存在完整的 C++ 符号。.textVMA等于文件偏移量(0xe63c000);所有地址都是分析VMA。其他版本会有所不同。
摘要
BarnaCore 是传统的 TPU 嵌入加速器(从 Jellyfish 到 Pufferfish 的芯片代)。它的 Pufferfish 一代 (pxc/pfc) 指令字是一个 32 字节/256 位 VLIW 捆绑,由 SparseCore 编解码器使用的相同位打包机制进行编码 — 单个 BitCopy(dst, dst_bitoff, src, src_bitoff, nbits) 原语 (@0x1fa0a900) 在绝对捆绑位位置写入字段。有两个捆绑包个性共享相同的 32 字节字宽:定序器捆绑 (BarnaCoreSequencerBundle),一个 2 宽双标量控制/存储器字,以及 通道捆绑 (BarnaCoreChannelBundle),一个 6 槽矢量数据路径字,每个周期执行一次全流水线嵌入行变换。两者均由 pufferfish::isa::EncoderPfBarnaCore{Sequencer,Channel} 生成,其 BundleSizeBytes() 访问 return 32(@0x1d229220、@0x1d22bb00 - 在反编译中得到确认)。
逆向工程技术反映了 SparseCore SCS/TEC 的工作:个性化 BarnaCore{Sequencer,Channel}CodecBase::Encode 调度程序将输出缓冲区 Span(指针 + 长度)保存在固定寄存器中,并将其不变传递给每个每个插槽 Encoder::Encode,因此每个插槽以捆绑相对的方式写入 —即绝对位偏移量。每个字段的 (dst_bitoff, nbits) 对来自 mov esi,IMM / mov r8d,IMM 紧邻其 BitCopy 调用之前;每个操作 6 位硬件操作码值来自写入操作码字段的 mov QWORD PTR[rbp-0x18],N 常量。编解码器模板名称是结构基本事实:BarnaCoreChannelCodecBase<BarnaCoreChannelBundle, BarnacoreChannelPredication, …VectorExtendedResult{Decoder,Encoder}, …VectorStore…, …VectorLoad…, …VectorAlu0…, …VectorAlu1…, …Scalar…>::Encode (@0x1d22c560) 按调度顺序枚举六个插槽。
本页记录了重新实现者必须重现的四个工件:(1) 定序器捆绑位布局 — 两个 27 位标量槽加上四个 16 位立即数; (2) 通道捆绑位布局 — 六个槽加四个立即数; (3) BcsMetadataAccessor描述符格式——由BcsProgramMetadataType索引的14类型平面SMEM字表; (4) MigrateInstruction 序数映射 — Alu0↔Alu1 矢量通道交换集,其中 54 个操作与通道无关,其中 7 个操作是通道锁定的。按原始顺序排列的每操作操作码名册、嵌入降低数据路径以及此镜像的 SparseCore 捆绑包均由同级页面拥有(请参阅 交叉引用)。
重新实现,合约为:
- 位打包模型:每个字段都是
BitCopy(buf, absolute_bitoff, src, src_bitoff, nbits);调度程序在所有时隙中重复使用一个Span,因此位偏移是捆绑绝对的,而不是相对于时隙的。 - 两个 32 字节捆绑布局:序列器(使用位 3..132)和通道(使用位 12..238),每个都有其插槽/操作码/预测/立即放置。
- 两个 Sequencer 管道共享的 27 位标量槽模板(与 SparseCore SCS 位相同):
operand-y / operand-x / dest / OPCODE / predication。 BcsMetadataAccessor:每个类型的 SMEM 字基数/计数数组 + 每个字段偏移量枚举;读取的字段为Sld(SmemWordAddress(base(type) + offset_enum))。MigrateInstruction映射:54 个操作 × 2 个方向 = 108 个模板,用于在 ALU 通道之间序列化/反序列化操作; 7 个行动没有模板(车道锁定)。
| 捆绑尺寸 | 32字节/256位(均为个性) |
| 尺寸配件 | EncoderPfBarnaCoreSequencer::BundleSizeBytes @0x1d229220 → 32; …Channel::BundleSizeBytes @0x1d22bb00 → 32 |
| 位打包器 | BitCopy(void*, int dst_bitoff, void const*, int src_bitoff, int nbits) @0x1fa0a900 |
| 定序器编解码器 | BarnaCoreSequencerCodecBase<…>::Encode @0x1d229780(2 个标量插槽) |
| 频道编解码器 | BarnaCoreChannelCodecBase<…>::Encode @0x1d22c560(6 个插槽) |
| 标量槽编码器 | 标量0 @0x1ee51ec0(基数位106);标量1 @0x1ee69000(基址79位) |
| 通道槽编码器 | ChannelScalar @0x1e87e6a0、VectorAlu0 @0x1e8927c0、VectorAlu1 @0x1e8b4ec0、VectorStore @0x1e8c5640、VectorLoad @0x1e8c4900、VectorExtendedResult @0x1e8c3c60 |
| 元数据访问器 | BcsMetadataAccessor 向量 @0xf9d8b80; MetadataSmemWordBase @0xf9d8ba0; MetadataSmemWordCount @0xf9d8c40 |
| 迁移地图 | PufferfishBarnaCoreChannelEmitter::MigrateInstruction<Alu0_X, Alu1_X> — 108 个实例(54 个操作 × 2) @0x140d17c0..0x140d6c00 |
| DMA 缓冲区宽度 | TpuTypedHostDmaBuffer<unsigned char, 32>(通道程序编码器上的 Li32E 模板 arg) — 32 字节对齐 |
1. Bundle编码模型
用途
两个 BarnaCore 包都是平面 256 位字,其字段由共享位复制原语在绝对位置写入。了解编码模型是读取下面每个偏移量表的先决条件:将每个插槽位偏移量视为相对于插槽的重新实现者会错误放置每个字段,因为调度程序不会对每个插槽的缓冲区进行重新设置。
入口点
EncoderPfBarnaCoreChannel::EncodeBundle (0x1d22b780)
└─ EncodeBundleInternal (0x1e87d580)
└─ BarnaCoreChannelCodecBase<…>::Encode (0x1d22c560) ── buf.ptr in %r14, buf.len in %rbx
├─ VectorExtendedResultEncoder::Encode (0x1e8c3c60) ── same Span
├─ VectorStoreEncoder::Encode (0x1e8c5640) ── same Span
├─ VectorLoadEncoder::Encode (0x1e8c4900) ── same Span
├─ VectorAlu0Encoder::Encode (0x1e8927c0) ── same Span (called per oneof form)
├─ VectorAlu1Encoder::Encode (0x1e8b4ec0) ── same Span
└─ ChannelScalarEncoder::Encode (0x1e87e6a0) ── same Span
└─ (each field) BitCopy (0x1fa0a900)
```text
定序器路径的形状相同:`EncoderPfBarnaCoreSequencer::EncodeBundle (0x1d228ea0)` → `BarnaCoreSequencerCodecBase<…>::Encode (0x1d229780)` → `{Scalar0,Scalar1}Encoder::Encode`。
### 算法
```c
// Models BarnaCoreChannelCodecBase<…>::Encode @0x1d22c560.
// a3 = buf.ptr, a4 = buf.len (absl::Span<unsigned char>).
function ChannelCodec_Encode(bundle, buf_ptr, buf_len): // %r14 = buf_ptr, %rbx = buf_len
// The Span is NEVER rebased: every slot encoder receives (buf_ptr, buf_len)
// unchanged, so each writes at bundle-absolute bit offsets.
EncodeSlot(bundle.extended_result, buf_ptr, buf_len) // 0x1e8c3c60
EncodeSlot(bundle.store, buf_ptr, buf_len) // 0x1e8c5640
EncodeSlot(bundle.load, buf_ptr, buf_len) // 0x1e8c4900
EncodeSlot(bundle.alu0, buf_ptr, buf_len) // 0x1e8927c0
EncodeSlot(bundle.alu1, buf_ptr, buf_len) // 0x1e8b4ec0
EncodeSlot(bundle.scalar, buf_ptr, buf_len) // 0x1e87e6a0
// tail: validation logging only — no separate predication / check-byte write;
// predication is emitted inline by each slot encoder.
function EncodeField(buf, op): // per-op helper
BitCopy(buf, DST_BITOFF, &src, SRC_BITOFF, NBITS) // 0x1fa0a900
// ^esi imm ^ ^ecx imm ^r8d imm
// OPCODE value comes from `mov QWORD PTR[rbp-0x18], N` before the opcode BitCopy.QUIRK — 下面每个表中的位偏移量都是捆绑绝对,从
mov esi,IMM立即馈送BitCopy恢复。它们不与插槽相关。对于两个标量管道,槽相关模板(操作数 y@+0 … OPCODE@+16 … predicate@+22)是相同的 27 位形状;绝对位置仅因插槽基数而异(Scalar1 为 79,Scalar0 为 106)。注意 — 编解码器调度程序的尾部是纯粹的
absl::log_internal验证,而不是帧字节写入。PufferfishCodecMetadata::BundleCheckByte/BundleSizeBytes(TC型0x55校验字节/0x33=51成帧)属于TpuSequencerType=0; BarnaCore 编码器通过TpuSequencerType=1路由,而它们自己的BundleSizeBytes()直接返回 32,没有校验字节。
功能图
| 功能 | 地址 | 角色 |
|---|---|---|
BitCopy | 0x1fa0a900 | 位粒度字段写入器; (dst, dst_bitoff, src, src_bitoff, nbits) |
BarnaCoreSequencerCodecBase<…>::Encode | 0x1d229780 | 定序器调度器;在两个标量插槽中重复使用一个 Span |
BarnaCoreChannelCodecBase<…>::Encode | 0x1d22c560 | 通道调度器;在 6 个插槽中重复使用一个 Span |
EncoderPfBarnaCoreSequencer::BundleSizeBytes | 0x1d229220 | return 32 |
EncoderPfBarnaCoreChannel::BundleSizeBytes | 0x1d22bb00 | return 32 |
2. 音序器捆绑包 (InstBits_BarnaCorePxcHwMode)
用途
Sequencer 捆绑包是一个 2 宽双标量 VLIW,承载控制流和 SMEM 访问 ISA:分支、调用、栅栏、同步/完成、DMA 描述符、SMEM 加载/存储以及标量整数/浮点 ALU。两个 27 位标量槽(Scalar0、Scalar1)以 27 位间隔堆叠,并共享捆绑包低位中的四个 16 位立即槽区域。符号 InstBits_BarnaCorePxcHwMode(@0x33931f0,LLVM 后端 TPUMCCodeEmitter::getBinaryCodeForInstr 内的静态 .rodata 表 - 此硬件模式包的每指令位模式表)是下面从原始编码器解码的布局的独立编译器端基本事实。
编码
该捆绑包仅使用 256 位(较低的约 17 个字节)中的 3..132 位。位 0..2 和 133..255 是保留/未写入的 — 通过扫描每个标量操作编码器和两个调度器头来确认;最大写入位为 132。高 16 字节是填充,因此定序器和通道捆绑共享相同的物理字宽(因此具有相同的 32 字节 DMA 传输单元),即使定序器仅填充下半部分。
每个标量槽都是 27 位模板(槽相关):operand-y @+0/w5、operand-x @+5/w6(ScalarY 型 6 位选择器,命名标量寄存器或四个立即槽之一)、dest @+11/w5、 OPCODE @+16/w6、predication @+22/w5。这与 SparseCore SCS 标量模板位相同;唯一的差异是 BarnaCore 预测是单个 5 位字段(BarnaCoreSequencerScalar{0,1}PredicationField,均以符号形式确认)而不是 SCS 多字段四元组。
Sequencer bundle (32 B / 256 bits; only bits 3..132 written)
bit: 15 31 47 63 79 ............ 105 106 ........... 132 133 .......... 255
+-------+-------+-------+-------+ +------------------+ +------------------+ +---------------+
| Imm0 | Imm1 | Imm2 | Imm3 | | Scalar1 slot | | Scalar0 slot | | RESERVED |
| w16 | w16 | w16 | w16 | | 27 bits @79 | | 27 bits @106 | | (unwritten) |
+-------+-------+-------+-------+ +------------------+ +------------------+ +---------------+
opcode@95 pred@101 opcode@122 pred@128
```text
#### Scalar0 插槽(基数 106;操作码值 = §4 表)
| 字段 | 基位 | 宽度 | 槽偏移 | 角色 |
|---|---|---|---|---|
| `SyField`(操作数 y) | 106 | 5 | +0 | 标量寄存器选择器 |
| `SxField`(操作数 x) | 111 | 6 | +5 | 标量寄存器或立即槽(`ScalarY` 样式) |
| `DestField` | 117 | 5 | +11 | 结果标量寄存器选择器 |
| `OPCODE` | 122 | 6 | +16 | 6位硬件操作码 |
| `PredicationField` | 128 | 5 | +22 | `BarnaCoreSequencerScalar0PredicationField` |
#### Scalar1 插槽(基数 79;操作码值 = §4 表)
| 字段 | 基位 | 宽度 | 槽偏移 | 角色 |
|---|---|---|---|---|
| 操作数 y | 79 | 5 | +0 | 标量寄存器选择器 |
| 操作数 x | 84 | 6 | +5 | 标量寄存器或立即数(`ScalarY` 样式) |
| 目标 | 90 | 5 | +11 | 结果标量寄存器选择器 |
| `OPCODE` | 95 | 6 | +16 | 6位硬件操作码 |
| `PredicationField` | 101 | 5 | +22 | `BarnaCoreSequencerScalar1PredicationField` |
#### 共享直接槽(两个标量管道)
| 字段 | 基位 | 宽度 |
|---|---|---|
| `Imm0Field` | 15 | 16 |
| `Imm1Field` | 31 | 16 |
| `Imm2Field` | 47 | 16 |
| `Imm3Field` | 63 | 16 |
> **明白了 —** DMA 操作是 **oneof-lane**:`ScalarDmaSimple`/`ScalarSingleStridedDma`/`ScalarGeneralDma` 不适合单个标量插槽。它们的操作码使用 Scalar0 操作码字段 (@122),但描述符(源/目标地址、核心 id、内存 id、长度、目标同步标志、dma 类型 — 来自 `ScalarDmaSimple{Source,Dest}{Address,CoreId,MemoryId}/Length/DestSyncFlag/DmaType0` 字段访问器的名称)溢出 Scalar1 区域、四个立即槽和额外低位。 `ScalarGeneralDma` (`@0x1ee55120`) 是最宽的,跨越位 0..127(整个低 16 字节)。重新实现者必须将 DMA 捆绑视为消耗整个双标量容量,而不是一个通道。
### 功能图
| 功能 | 地址 | 角色 |
|---|---|---|
| `BarnaCoreSequencerScalar0Encoder::Encode` | `0x1ee51ec0` | Scalar0 槽编码器;基数106,跳转表`@0xb84559c`(界限≤0x3e) |
| `BarnaCoreSequencerScalar1Encoder::Encode` | `0x1ee69000` | Scalar1 槽编码器;基数79,跳转表`@0xb845698`(界限≤0x3c) |
| `ScalarIntAdd`(标量0) | `0x1ee55ee0` | op=0x20; Sy@106/Sx@111/Dest@117 |
| `ScalarGeneralDma`(标量0) | `0x1ee55120` | 最宽运算;跨越位 0..127 |
| `ScalarStoreSmemAbsolute`(标量1) | `0x1ee6ace0` | op=0x6 |
---
## 3. 通道捆绑包
### 用途
通道束是 6 时隙矢量数据路径。在一个周期中,它执行完全流水线的嵌入行变换:推进特征长度循环,在两个通道上运行两个向量 ALU 操作,存储前一行,加载下一行,并排出 EUP(超越单元)结果。六个槽被放置在升序的绝对位位置;编解码器模板 (`@0x1d22c560`) 按 ExtendedResult / Store / Load / Alu0 / Alu1 / Scalar 的顺序列出它们。
### 编码
该捆绑包填充其 256 位帧的**位 12..238**;位 0..11 和 239..255 被保留(最大写入位 = 238,其中第四个立即数结束)。两个矢量 ALU 通道相距 33 位(一个 31 位槽加上一个 2 位通道间间隙)。每个 `VectorAlu` 编码器还在位 35/37/39 处写入一个共享 2 位字段组 — 矢量区域基础上的矢量通道/掩码标头(从 `VxField`/`YSrc` 访问器邻域推断的角色;位位置准确)。
```text
Channel bundle (32 B / 256 bits; bits 12..238 written)
12 35 62 67 92 95 100 125 126 128 147 149 167 172 175 191 207 223 238
+----------+--------+--------+----+--------+----+--------+----+------+------+----+-------+------+------+------+
| Channel | (2-bit |VectorAlu0| | VectorAlu1| |VectorStore| VectorLoad |VExtRes| Imm0 | Imm1 | Imm2 | Imm3 |
| Scalar | lane | opcode@67 | | opcode@100| | pred@128 | pred@149 |pred@167| w16 | w16 | w16 | w16 |
| loop ctl | hdr@35 | pred@62 | | pred@95 | | form@126 | form@147 | |
+----------+--------+----------+-+-----------+-+-----------+------------+--------+------+------+------+------+| 插槽 | 编码器 | 位范围 | 操作码/预测位 | 角色 |
|---|---|---|---|---|
ChannelScalar | 0x1e87e6a0 | 12 .. 59 | 型@12/w2;计数@16/w8 | 特征长度循环控制(LoopStart/NormalOp/OpBranch) |
VectorAlu0 | 0x1e8927c0 | 35 .. 92 | 操作码@67/w6;预测@62/w5 | 矢量 ALU 通道 0(承载 VectorFloatMul;54 个共享操作) |
VectorAlu1 | 0x1e8b4ec0 | 35 .. 125 | 操作码@100/w6;预测@95/w5 | 矢量 ALU 通道 1(承载 VectorFloatAdd/Sub + 4 个班次) |
VectorStore | 0x1e8c5640 | 126 .. 147 | 表格@126/w2;预测@128/w5 | 嵌入行存储(Base/Source/FeatureLen/Stride) |
VectorLoad | 0x1e8c4900 | 147 .. 167 | 表格@147/w2;预测@149/w5 | 嵌入行负载(Base/Dest/FeatureLen) |
VectorExtendedResult | 0x1e8c3c60 | 167 .. 174 | pred@167/w5; @172/w1,@173/w2 | EUP-结果流失 |
ScalarImmediates | (开放中) | 175 .. 238 | 4×16位@175/191/207/223 | 共享文字 (Imm0..Imm3) |
VectorAlu 模板
相对于操作码字段的槽: OPCODE w6 位于底部,其上方有 4 个 5 位 VREG 操作数选择器(Dest/Vx/YSrc/YSrcVreg — 来自 VectorFloatMul{Dest,Vx,YSrc,YSrcVreg}Field 的名称访问器,全部以符号形式确认),以及其下方的 5 位预测字段。 VectorFloatMul 还声明 Imm0..Imm5Field(已确认)。
ChannelScalar 回路控制器
ChannelScalar 插槽是每周期特征长度循环定序器。其字段(全部确认为BarnaCoreChannelScalar*Field符号):LoopStartLoopInstructionCount、LoopStartPipelineDepth、OpBranch{BranchTargetPc,BranchType,BranchPred}、OpShift{,PipelineStage}、OpPush、PredFeatureId、ProgEnd以及一系列AddLoopIndexTo{ShiftAmount,VldDst,VstSrc,V0Dst,V0X,V0YReg,V0VselectMask,V1Dst,V1X,V1YReg,V1VselectMask} 选择器将循环索引添加到每通道操作数寄存器。
注意 — 解码器声明六个通道立即字段(
Imm0..Imm5Field,例如以符号形式确认的VectorFloatMulImm4Field/Imm5Field),但每个采样操作编码器仅在 175/191/207/223 处写入四个(4 × 16 位填充位) 175..238,正是捆绑包的写入最大值)。Imm4/Imm5在 v0.0.40 中已声明但未写入 — 保留或特定于 op 形式(对其位置的置信度较低,因为编码端从未设置它们)。
功能图
| 功能 | 地址 | 角色 |
|---|---|---|
BarnaCoreChannelVectorAlu0Encoder::Encode | 0x1e8927c0 | Alu0插槽;操作码@67/w6,pred@62/w5;跳转表@0xb834e8c(界限≤0x2e) |
BarnaCoreChannelVectorAlu1Encoder::Encode | 0x1e8b4ec0 | Alu1插槽;操作码@100/w6, pred@95/w5 |
BarnaCoreChannelScalarEncoder::Encode | 0x1e87e6a0 | 回路控制器;输入@12/w2,计数@16/w8 |
VectorFloatMul (Alu0) | 0x1e894420 | 操作码值 0x7 |
VectorTanh (Alu0) | 0x1e89edc0 | 操作码值 0x33 |
VectorReciprocal (Alu0) | 0x1e89ee40 | 操作码值 0x34 |
4. 硬件操作码值(6 位字段)
6 位操作码字段写入每个操作的文字值 (mov QWORD PTR[rbp-0x18],N)。这些是硬件操作码值,与 proto-oneof 序数分开的排序;这两个订单是独立的,现在都已固定。
Scalar0 / Scalar1 调度维度
标量管道以相同的值共享一个公共 ALU 尾部,并在间隙中的仅管道操作上进行拆分:
| 轴 | 值 | 源码 |
|---|---|---|
| 共享标头 | 0x00..0x03 = Noop/同步(0x1)/Pop(0x2)/延迟(0x3) | 两个跳转表 |
| 共享ALU尾部 | IntAdd=0x20,IntSub=0x21,And=0x22,Or=0x23,Xor=0x24,Move=0x2e, IntEqual=0x30 — 两个管道中的值相同 | 每操作 mov QWORD |
| 标量 0-仅限 | 分支{Abs,Rel,Reg}=0x8/0x9/0xa,调用=0xc..,围栏=0x10,Dma=0x12, IssueFsm=0x15,ReadRegs=0x1d,ConvI2F=0x1e,FloatMul=0x27,UintMul=0x28,FloatMax=0x29, IsInfoOrNan=0x3e | Scalar0 编码器 |
| 仅标量1 | LoadSmem=0x4,LoadSmemOffset=0x5,StoreSmemAbsolute=0x6,ReadDone=0x16,WriteDone=0x17, ReadPublicAccess=0x18、WritePublicAccess=0x19、FloatAdd=0x25、FloatSub=0x26 | 标量1编码器 |
所有七个 Sync* 操作共享操作码 0x1,通过子表单字段进行区分(≤0x3e 适合 6 位字段)。
通道 VectorAlu0
| 操作码 | Op | 操作码 | Op |
|---|---|---|---|
| 0x03 | VectorOr | 0x20 | VectorIntEqual |
| 0x04 | VectorXor | 0x27 | CreateSublaneMask |
| 0x07 | VectorFloatMul | 0x2f | CreateLaneMask |
| 0x08 | VectorFloatMax | 0x30 | VectorReciprocalSquareRoot |
| 0x09 | VectorFloatMin | 0x31 | VectorPow2 |
| 0x18 | VectorLaneId | 0x32 | VectorLog2 |
| 0x1e | VectorRelux | 0x33 | VectorTanh |
| 0x1f | VectorMove | 0x34 | VectorReciprocal |
| 0x35 | MoveDataUnchanged |
QUIRK — EUP 超越块在
0x30..0x34的硬件操作码空间中连续(rsqrt → pow2 → log2 → tanh → recip),与原始 oneof 中的连续完全相同。这是块内 EUP 顺序的独立确认(来自 6 位操作码值,而不是原始序数)。VectorRelux(0x1e) 位于早期 ALU 范围,与先验运行“分离”,反映了其作为嵌入激活而不是先验运行的角色。
5. BcsMetadataAccessor 描述符格式
用途
每操作嵌入元数据(聚集/分散操作所需的编程表面:行所在的位置、缓冲区有多大、哪个分区列、哪个 HBM 地址)不在捆绑包中 — 它作为平面的每类型字数组存在于 SMEM 中。 BcsMetadataAccessor 是运行时读取器。这是 SparseCore TAC 描述符表的 BarnaCore 模拟:描述符位于 SMEM 中(由驱动程序的 SetBarnaCoreFeature* 路径编程),发射器将其加载到标量寄存器中,并且地址数学在共享标量 ALU 上运行。
编码
访问器对象保存两个由 BcsProgramMetadataType(已确认的枚举符号)索引的驱动程序填充的 int32 数组:this[+0x10] 处的 SMEM 字 base(长度为 [+0x18])和 this[+0x28] 处的字 count(长度为[+0x30])。 MetadataSmemWordBase (@0xf9d8ba0) 和 MetadataSmemWordCount (@0xf9d8c40) 是边界检查查找。读取的描述符字段为:
// field(type, offset_enum) =
value = Sld( SmemWordAddress( MetadataSmemWordBase(type) + offset_enum ) );
// SmemWordAddress @0xf9d9720 ; LloRegionBuilder::Sld @0x1d516a20
```text
每个访问器的类型号来自访问器主体内的 `mov esi,N; call MetadataSmemWordBase` 站点。 14 种类型(损坏的访问器符号均在 `…_names.json` 中得到确认):
| 型 | `BcsProgramMetadataType` | 访问器方法 | 地址 | 偏移量枚举 |
|---|---|---|---|---|
| 0x1 | DedupTransfer | `LoadDedupTransferMetadata` | `0xf9d90e0` | `BcsDedupTransferMetadataOffset` |
| 0x2 | PassHeader | `LoadPassHeaderMetadata` | `0xf9d8d40` | `BcsPassHeaderMetadataOffset` {2,3,4,5,6,..} |
| 0x3 | 有效负载位置 | `LoadPayloadLocationMetadata` | `0xf9d8da0` | `BcsPayloadLocationMetadataOffset`(每个 ID) |
| 0x4 | LocalBuffer | `LoadLocalBufferSize` | `0xf9d8e40` | — |
| 0x5 | RemoteBufferSize | `LoadRemoteBufferSize` | `0xf9d8f80` | — |
| 0x6 | BmemWordAddress | `LoadBmemWordAddressFromMetadata` | `0xf9d9140` | — |
| 0x7 | RemoteBufferOffset | `LoadRemoteBufferOffset` | `0xf9d8fe0` | — |
| 0x8 | 分区柱 | `LoadPartitionColumn` | `0xf9d92e0` | (基数+0,无偏移) |
| 0x9 | 分散组 | `LoadScatterGroup` | `0xf9d9340` | — |
| 0xa | BarnaCore位置 | `LoadBarnaCoreLocation` | `0xf9d93a0` | — |
| 0xb | TensorCoreLocation | `LoadTensorCoreLocation` | `0xf9d9460` | — |
| 0xc | 绝对HBm | `GetBarnaCoreAbsoluteHbmAddress` | `0xf9d9520` | — |
| 0xd | TensorCoreDmaAddr | `GetBarnaCoreAbsoluteHbmAddressForTensorCoreDma` | `0xf9d95c0` | — |
| 0xe | BackwardPassSlotSelector | `Load/StoreBackwardPassSlotSelector` | `0xf9d9660` / `0xf9d96c0` | — |
`LoadCommandMetadata` (`@0xf9d8ce0`) 将类型作为运行时参数(`BcsCommandMetadataOffset` 枚举,已确认)。构造函数为`BcsMetadataAccessor(TpuTopology const*, int, int, absl::Span<int const>)`(`@0xf9d8b80`)。
> **注意 —** 符号表还带有上面未列举的 `LoadTensorCoreBufferSelector` 和 `LoadTpuBatchCount` 访问器 — 同一 SMEM 字模型上的其他元数据读取器(它们的类型号没有单独解码;高置信度它们遵循相同的 `base(type)+offset` 模式,低置信度在其特定类型索引上)。
---
## 6. `MigrateInstruction` 序数图
### 用途
`PufferfishBarnaCoreChannelEmitter::MigrateInstruction<Alu0_X, Alu1_X>`(以及相反的 `<Alu1_X, Alu0_X>`)是矢量 ALU **通道交换** 机制。当一个 ALU 通道空闲时,调度程序使用它在两个 ALU 通道之间移动向量运算。该映射是 Alu0/Alu1 通道不对称性的运行时、消息级证明:`Migrate` 模板完全适用于与通道无关的操作,而对于通道锁定操作则不存在。
### 编码
每个 `MigrateInstruction` 主体都是一个原始往返:`SerializeToString` (`@0x210580c0`) 为源通道消息,然后 `ParseFromString` (`@0x21057460`) 为目标通道消息类型。两种车道类型共享其场地布局,因此往返是无损的。 op 消息类型位于 `asic_sw::deepsea::pxc::pfc::isa::BarnaCoreChannelVectorAlu{0,1}_<Op>` 中。
有 **108 个实例 = 54 个操作 × 2 个方向**(`@0x140d1400..0x140d6c00`;`<Alu0_Noop,Alu1_Noop>` `@0x140d17c0`、`<Alu0_VectorTanh,Alu1_VectorTanh>` `@0x140d4c80`)。 54个可迁移操作(符号中均确认为 `BarnaCoreChannelVectorAlu0_<Op>` ↔ `Alu1_<Op>` 模板对):
```text
Noop, VectorIntAdd, VectorIntSub, VectorAnd, VectorOr, VectorXor,
VectorFloatMax, VectorFloatMin, VectorLaneId, VectorSublaneCircularRotateDown,
VectorRelux, VectorMove, VectorClampSymmetric, VectorPopCount,
VectorCountLeadingZeros, VectorSelectVmsk0..7 (8), VectorPackAsHalfFloats{Interleaved,Compressed},
VectorUnpackHalfFloats{Upper,Lower}, VectorConvert{IntToFloat,FloatToInt},
VectorExtractExponent, VectorExtractSignificand, VectorComposeFloat,
VectorInt{Equal,NotEqual,Greater,GreaterEqual,Less,LessEqual}, VectorIntAddCarryOut,
CreateSublaneMask, VectorFloat{Equal,NotEqual,Greater,GreaterEqual,Less,LessEqual},
VectorFloatIsInfOrNan, CreateLaneMask, VectorReciprocalSquareRoot, VectorPow2,
VectorLog2, VectorTanh, VectorReciprocal, MoveDataUnchanged7 个通道锁定操作没有 Migrate 模板 - 调度程序无法移动它们:
| Op | 锁定 | 原因 |
|---|---|---|
VectorFloatMul | 铝0 | 浮乘通道 |
VectorFloatAdd | 铝1 | 浮动添加车道 |
VectorFloatSub | 铝1 | 浮动添加车道 |
VectorLogicalShiftLeft | 铝1 | 移位单元 |
VectorLogicalShiftRight | 铝1 | 移位单元 |
VectorArithmeticShiftRight | 铝1 | 移位单元 |
VectorRoundingArithmeticShiftRight | 铝1 | 移位单元 |
QUIRK — 不对称是真正的硬件结构:float-mul 仅适用于 Alu0,float-add/sub 且所有四个移位均仅适用于 Alu1。假设两条通道可以互换的调度程序将错误地放置这七个操作。
Migrate模板的存在/不存在是通道能力表。注意 — 有零
Scalar0↔Scalar1Migrate实例。标量双重问题是通过FindFreeScalarSlot<Scalar0_X, Scalar1_Y>模板实例化在计划时间静态解决的,而不是通过运行时消息迁移来解决。 (全二进制MigrateInstruction<…>模板实例计数为 222 — 上面的 108 个 BarnaCore 通道对加上PufferfishTensorCoreEmitter中的 114 个;BarnaCore 通道集是上面地址范围中的 108 个。)
相关组件
| 名称 | 关系 |
|---|---|
BarnaCoreSequencerCodecBase / BarnaCoreChannelCodecBase | 两个个性捆绑调度程序;跨插槽重复使用一个 Span |
EncoderPfBarnaCore{Sequencer,Channel} | pufferfish::isa 编码器; BundleSizeBytes() == 32 |
BitCopy (@0x1fa0a900) | 共享的SparseCore/BarnaCore位打包器 |
PufferfishBarnaCoreChannelEmitter | 拥有MigrateInstruction;车道交换调度程序钩子 |
交叉引用 {#cross-references}
- 概览 — BarnaCore,传统嵌入加速器:该捆绑包位于管道中的位置
- BCS Scalar0/Scalar1 ISA — 每操作控制+内存 ISA 名册,其操作码 §4 给出硬件值
- 合并 ALU 位布局 —
VectorResultDestination/BaseAddressEncoding,第 3 节中引用的向量 ALU 操作数选择器 - JF/DF 16 字节地址处理程序包 — 传统(非河豚)BarnaCore 捆绑包;由直接结构写入填充的单独的 16 字节字,而不是
BitCopy - 指数 — 第九部分 — SparseCore 和 BarnaCore / BarnaCore(旧版 v2–v4)