JF/DF BarnaCore 地址处理程序包
此页上的每个地址、位偏移量、掩码和枚举值都是从
libtpu-0.0.40-cp314轮中的libtpu.so读取的(内部版本libtpu_lts_20260413_b_RC00、内部版本号89edbbe81c5b328a958fe628a9f2207d)。 ELF 没有被剥离;存在完整的 C++ 符号。.text和.rodataVMA 等于其文件偏移量(.text0xe63c000、.rodata0x84a0000),因此直接读取原始描述符字节。所有地址都是分析 VMA。其他版本会有所不同。
摘要
BarnaCore 地址处理程序 (BCAH) 是 Jellyfish/Dragonfish 嵌入地址个性 — tpu::TpuSequencerType = BarnaCoreAddressHandler = 2(C++ 枚举 TpuSequencerTypeToString @0x20b362e0 索引:TC=0、BCS=1、BCAH=2, SCS=3、TAC=4、TEC=5;原始线枚举 TpuSequencerTypeProto 带有额外的 INVALID=0,因此其值为 +1),是完整 BarnaCore 定序器 (BCS = 1) 的 v3 时代对应项。它的指令字是一个23字节/184位VLIW包,由直接结构字段写入填充:每个时隙编码器使用硬编码的shl N; and MASK; or常量对包的qwords/dword/word/byte进行读取-修改-写入。这是与 Pufferfish BCS 路径“根本不同”的机制,后者通过共享 BitCopy 原语与绝对位 Span 打包每个字段(请参阅 BCS 32 字节捆绑包)。这两种编码通过独立的方式在各代芯片上达到相同的嵌入数据路径系列; JF/DF 直写编解码器早于 BCS BitCopy 编解码器。
该捆绑包是一个 3 路 VLIW:一个 Common 标头(迭代状态 + 操作数选择器 + 两个立即数)、一个 ScalarSlot(控制通道)和一个 VectorSlot(5 宽矢量数据路径)。所有三个区域同时在专用的、不重叠的位位置上运行;仅*ScalarSlot(Loop/ShiftMask/Push/Branch/prog_end)内的子表格和VectorSlot*内(Store/Load/Alu0/Alu1/Result) 是互斥的。因此,一个捆绑包在单个周期中表示:推进特征长度循环、分支或结束程序、运行两个向量 ALU 操作、存储前一个嵌入行、加载下一个、排出 EUP 结果、应用每个操作数索引覆盖并携带两个 16 位文字。
此页面记录了重新实现者必须重现的三个工件:(1) 23 字节捆绑位布局 — Common/ScalarSlot/VectorSlot 的绝对位图、直接结构写入机制和 32 字节对齐的 23 字节 DMA 步长; (2) 5位BCS预测字段值法则和16位BarnaCorePredication.Condition枚举; (3) 立即操作数模型 — 由 YIsImm 分配的两个 16 位 ImmSlot。 Pufferfish 32 字节 BCS 序列器/通道包、标量 ISA 名册和合并的向量 ALU 操作码空间均由同级页面拥有(请参阅 交叉引用)。
重新实现,合约为:
- 编码是直接struct write,而不是
BitCopy。 每个槽编码器接收相同的23字节BarnaCoreAddressHandlerBundleBits*并将其字段写入qword0 (+0) / qword1 (+8) / dword (+16) / word (+20) / 字节 (+22) 带有文字移位/掩码常量。在 BCSBitCopySpan 上对 BCAH 进行建模的重新实现者会错误地构建每个字段。 - 每束 23 字节,32 字节对齐。 DMA 缓冲区为
(3*N)*8 - N = 23*N字节,posix_memalign为 32;每个包占用 23 个连续字节。 - 不存在的时隙被编码为
kNeverExecute(0x1f),而不是作为不同的操作码。 在对任何时隙进行编码之前,调度程序会使用kNeverExecute预填充所有六个标量/向量时隙预测字段;当前的槽会覆盖它自己的字段。槽存在是一个预测问题。 - 5位预测字段=
condition[3:0] | (~value)<<4。Always= 0x0f (kAlwaysExecute),Never= 0x1f (kNeverExecute)。条件是嵌入迭代边界谓词字母表(16 个值,1 个别名)。 - JF 和 DF 仅在标量槽超集上有所不同。 Dragonfish 标量槽编码器调用 Jellyfish 助手,然后添加
Branch+prog_end。相同的 23 字节帧,相同的向量槽。
| 个性 | BCAH — BarnaCore 地址处理程序; tpu::TpuSequencerType = 2(C++ 枚举:TC=0、BCS=1、BCAH=2)(水母/龙鱼) |
| 捆绑尺寸 | 23字节/184位,直接结构体写入; DMA 步长 23*N,32 字节对齐 |
| 位打包器 | none — 23 字节结构的每槽读取-修改-写入 (shl N; and MASK; or) |
| 顶部编码器 | tpu::EncodeBarnaCoreAddressHandler<EncoderJf,…> @0x1e841640; <EncoderDf,…> @0x1e836ea0 |
| 捆绑调度程序 | EncoderJf::EncodeBarnaCoreAddressHandlerBundle @0x1e86fd80 |
| 结构图像 | qword0 +0(位 0..63) · qword1 +8 (64..127) · 双字 +16 (128..159) · 字 +20 (160..175) · 字节+22 (176..183) |
| 预测律 | pred5 = condition + ((16*value) ^ 0x10) = condition[3:0] | (~value)<<4;默认0x0f |
| 立即型号 | 2 × 16 位 ImmSlot (imm_0/imm_1) 由 YIsImm @0x14169c20 分配 |
| 信心 | 已确认(反编译的移位/掩码提取 + 23 字节跨步证明 + 原始字符串解码),除非一行另有说明 |
GOTCHA — BCAH 结构是 23 个字节,尽管
BundleSizeBytes报告 BarnaCore 组件为 16。 Jellyfish 编解码器元数据大小调整器JellyfishCodecMetadata::BundleSizeBytes@0x1ecf7460为其 BarnaCore 组件返回 16(组件 0 = TensorCore → 41;组件1 = BarnaCore → 16;DMA 和 HBM,BundleSizeBytesForHbm@0x1ecf74c0都同意),并且 概览 个性表和同级页面导航带有“16 B”数字。字节精确的 BCAH 编码器 证据更大:顶部编码器分配23*N,将指针每束前进 23,最高写入位为 180 (imm_1),因此BarnaCoreAddressHandlerBundleBits结构图像为 23 字节/184 位。 16字节编解码器数字与xmm0(qword0+qword1)低半部分顶部编码器存储首先匹配;该存储后面是单独的双字/字/字节存储,将结构携带到 23 个字节。将 23 视为地址处理程序结构布局的权威; “16 B”标签是编解码器元数据 BarnaCore 组件大小,用作枚举存在页面上的粗略个性标签。 [置信度:已确认 —23*N步幅 + 每时隙位偏移量达到 180; 16是BundleSizeBytes的BarnaCore组件返回。]
1. Bundle编码模型
用途
BCAH 捆绑包是一个平面 23 字节结构 (BarnaCoreAddressHandlerBundleBits),其字段由每个时隙编码器“就地”写入。没有共享的位复制原语,也没有相对于槽的变基:每个编码器接收相同的结构指针,并将其字段以硬编码的移位写入硬编码的 qword/dword/word/byte 成员。了解此机制是读取下面每个偏移量表的先决条件 - 偏移量是从每次存储之前的 <<N 移位和 & MASK 常量恢复的,而不是从 BitCopy 立即数恢复的。
入口点
tpu::EncodeBarnaCoreAddressHandler<EncoderJf,…> (0x1e841640) ── DMA buffer = 23*N, posix_memalign(.,0x20,.)
└─ (per bundle) EncoderJf::EncodeBarnaCoreAddressHandlerBundle (0x1e86fd80)
├─ prefill 6 slot preds with kNeverExecute (@6/48/79/110/126/141)
├─ write Common header fields (compared_feature_id, indexed_*, vs0/vs1/vs2, branch_target_pc…)
├─ ScalarSlot encoder (vtable +152) — Loop/ShiftMask/Push (+ DF Branch/prog_end)
├─ EncodeBarnaCoreAddressHandlerVectorStore (0x1e86e020)
├─ EncodeBarnaCoreAddressHandlerVectorLoad (0x1e86e5c0)
├─ EncodeBarnaCoreAddressHandlerVectorAlu(0) (0x1e86f5c0) — lane 0
├─ EncodeBarnaCoreAddressHandlerVectorAlu(1) (0x1e86f5c0) — lane 1
└─ EncodeBarnaCoreAddressHandlerVectorResult (0x1e86eb40)龙鱼路径形状相同(tpu::EncodeBarnaCoreAddressHandler<EncoderDf,…> @0x1e836ea0,相同的 23*N 步幅);只有标量时隙编码器不同(§5)。
算法
// Models tpu::EncodeBarnaCoreAddressHandler<EncoderJf,…> @0x1e841640.
// a2 + 32 = num_bundles (int32).
function EncodeAddressHandler(program):
n = program.num_bundles // *(int*)(a2+32)
buf = posix_memalign(align=0x20, size=23*n) // (3*n)*8 - n = 23*n ; 32-byte aligned
p = buf
for i in 0 .. n-1:
bits = EncodeBarnaCoreAddressHandlerBundle(program.bundle[i]) // 0x1e86fd80 → 23-byte struct
// store the 23-byte struct image, member by member:
store_xmm(p, bits.qword0_qword1) // bytes 0..15 (vmovups)
store_dword(p+16, bits.dword) // bytes 16..19
store_word(p+20, bits.word) // bytes 20..21
store_byte(p+22, bits.byte) // byte 22
p += 23 // <-- the per-bundle stride is 23
return TpuTypedHostDmaBuffer<unsigned char, 32>{ buf, 23*n }
// Models a per-slot field write (no BitCopy; direct read-modify-write):
function WriteField(struct_member, value, shift, clear_mask):
struct_member = (value << shift) | (struct_member & clear_mask)QUIRK — 顶部编码器将结构存储为 16 字节
vmovups xmm0(qword0+qword1) 加上 三个标量存储(dword@16、word@20、byte@22),然后将指针前进 23。 16 字节 SIMD 存储仅涵盖位 0..127;双字/字/字节存储进位位 128..183。 DMA 缓冲区是 32 字节对齐(因此 SIMD 存储是合法的),但每个包的步幅是 23,而不是 16 或 32 — 由编码器循环中的_R14 += 23和23*N分配大小确认。 [信心:已确认。]注意 — 地址处理程序编码路径附加 无 检查字节。 TensorCore 的成帧字节机制(
tpu::TpuSequencerType= 0,41 字节 HardwareBundleBits)不用作 BCAH DMA 有效负载; 23 个原始结构字节是每个包的整个有效负载。 (每通道向量 ALU 主体确实调用EncoderJf::EncodeBundleInternal来构建 41 字节 TensorCore 编码,然后提取其指令位并将其合并到 qword1 中 — 请参阅§2 — 但没有校验字节到达 BCAH 缓冲区。)编解码器大小调节器JellyfishCodecMetadata::BundleSizeBytes@0x1ecf7460为其组件 0 (TensorCore) 报告 41 / 16 对于组件 1 (BarnaCore),但地址处理程序顶部编码器直接写入 23 个字节。
功能图
| 功能 | 地址 | 角色 |
|---|---|---|
tpu::EncodeBarnaCoreAddressHandler<EncoderJf,…> | 0x1e841640 | 顶部编码器; 23*N DMA 缓冲区,32 字节对齐 |
tpu::EncodeBarnaCoreAddressHandler<EncoderDf,…> | 0x1e836ea0 | DF顶部编码器;相同的 23*N 步幅 |
tpu::EncodeBarnaCoreAddressHandlerBundle<EncoderJf> | 0x1e837980 | std::vector<uint8> 单束形式 |
EncoderJf::EncodeBarnaCoreAddressHandlerBundle | 0x1e86fd80 | 每包调度程序; kNeverExecute 预填充 + 公共 + 槽调用 |
ApplyEupResultTargetWorkaround | 0x1e8478a0 | 唯一已知的读者;重用23*N步幅;修补结果区域 |
2. 23 字节捆绑位布局
用途
该捆绑包是 BarnaCoreAddressHandlerBundle 原型 = { common (f1), scalar (f2), vector (f3) }。 C++ 结构体映像保存三个子消息,这些子消息打包在 绝对 捆绑位位置;每个时隙编码器都以硬编码偏移量写入。与真实的原型 oneof(存储案例号)不同,编码器使用每个字段的 has-bits 和每个时隙的专用、非重叠位区域 - 因此标量、向量和公共都可以同时生效。该捆绑包是真正的 VLIW。
编码
结构体堆栈映像有五个成员:qword0(+0,位 0..63)、qword1(+8,位 64..127)、dword(+16,位 128..159)、word (+20,位 160..175),字节(+22,位 176..183)。位 181..183 被保留。调度程序用 kNeverExecute (§3) 预填充六个时隙预测字段,将 Common 标头写入 qword0/dword/word/byte,然后调用每个时隙编码器。
BarnaCoreAddressHandlerBundle (23 B / 184 bits; absolute bundle bits)
byte: 0 8 16 20 22
+--------+--------+--------+----+-+
| qword0 | qword1 | dword |word|b|
| 0..63 | 64..127| 128..159|...|.|
+--------+--------+--------+----+-+
ScalarSlot ┌ Loop bits 0..5
(control) │ ShiftMask pred 6..10
Common ┤ compared_feature_id 13..17
(header) │ indexed_* (6 bools) 18..23
│ vs0/vs1/vs2 (2b ea) 24..29
ScalarSlot │ Branch pred (DF) 30..34
(control) │ branch_type 36
│ branch_target_pc 37..43
└ prog_end (DF) 44
VectorSlot ┌ Alu0 pred 48..52
(datapath) │ Alu1 pred 79..83
│ Store slot 110..125 (TABLE B)
│ Load slot 126..140 (TABLE C)
└ Result slot 141..146 (TABLE D)
Common ┌ imm_0 (16b) 149..164
(literals) └ imm_1 (16b) 165..180
[181..183 reserved]表 A — 顶级位图
| 区域 | 位 | 源字段 | 角色 |
|---|---|---|---|
ScalarSlot.Loop | 0..5 | Loop.loop_size_minus_one (5b @1) | 循环行程计数(大小 − 1) |
ShiftMask 预测 | 6..10 | ScalarSlot.ShiftMask.predication | 5 位 BCS 预测 (§3) |
compared_feature_id | 13..17 | Common.compared_feature_id (5b) | COMPARE_FEATURE_ID 的操作数 |
indexed_* | 18..23 | Common.indexed_{load_dst,store_src,alu0_x,alu0_dst,alu1_x,alu1_dst} | 6 个每个操作数索引覆盖 |
vs0/vs1/vs2 | 24..29 | Common.vs0/vs1/vs2(各 2b) | 标量寄存器选择器(§4 表 G) |
Branch 预测 | 30..34 | ScalarSlot.Branch.predication | 5 位 BCS 预测(仅限 DF) |
branch_type | 36 | ScalarSlot.Branch.branch_type (1b) | 分支类(DF) |
branch_target_pc | 37..43 | ScalarSlot.Branch.branch_target_pc (7b) | 分支目标 PC (DF) |
prog_end | 44 | ScalarSlot.prog_end (1b) | 程序结束标记(DF) |
Alu0 预测 | 48..52 | VectorSlot.alu_0.predication | 5 位 BCS 预测,通道 0 |
Alu1 预测 | 79..83 | VectorSlot.alu_1.predication | 5 位 BCS 预测,通道 1 |
Store 插槽 | 110..125 | VectorSlot.store(表 B) | 嵌入行存储 |
Load 插槽 | 126..140 | VectorSlot.load(表C) | 嵌入行负载 |
Result 插槽 | 141..146 | VectorSlot.result(表D) | EUP-结果流失 |
imm_0 | 149..164 | Common.imm_0(f11、16b) | 16 位文字槽 0(<<21 进入双字,由 has 位 0x400 门控) |
imm_1 | 165..180 | Common.imm_1(f12、16b) | 16 位文字槽 1(<<37 进入双字,由 has 位 0x800 门控) |
上面的 Common 头字段是从调度程序 @0x1e86fd80 恢复的:compared_feature_id at v7 |= v12<<13; <<18/19/20/22/21/23 处的六个 indexed_* 布尔; vs0/vs1/vs2 在 <<24/26/28; imm_0 作为 16 位字段 <<21 放入双字(捆绑位 149,has 位 0x400),而 imm_1 将 <<37 放入双字(捆绑位 165,has 位 0x800)。 DF branch_target_pc 由 DF 标量槽编码器 @0x1e85e8a0 将 <<37 写入 qword0 (捆绑位 37)——一个不同的分支子表单字段,碰巧共享文字移位 37,但落在 qword0 中,而不是双字 imm_1。
注意 — VectorAlu 指令体是标准 JF 矢量 ALU ISA,合并到 qword1 中。
EncodeBarnaCoreAddressHandlerVectorAlu(lane,…)@0x1e86f5c0构建临时isa::Bundle,调用EncoderJf::EncodeBundleInternal(常规 JF 矢量 ALU 编码器),然后提取指令位并将它们合并到qword1 带有掩码0xffffc000000fffff(移位0x29/0x20/0x10)。因此,地址处理程序 ALU 操作的操作码/操作数空间等于主 JF 向量 ALU ISA;只有通道预测(通道 0 具有位0x4→ pred @48;通道 1 具有位0x8→ pred @79)是特定于地址处理程序的。 qword1 内合并的操作码/Vx/YSrc 位的每字段着陆位置是单独的 JF-ISA 解码(请参阅 交叉引用)。 [对合并机制的信心:高;合并字段位置在这里并不是孤立的。]
表 B — VectorSlot.Store (EncodeBarnaCoreAddressHandlerVectorStore @0x1e86e020)
r15 的结构底座; all 存储目标 qword1(+8,基位 64),因此捆绑位 = 64 + 移位。
| 字段 | 捆绑钻头 | 宽度 | 原型场 | 移位(在 qword1 上) |
|---|---|---|---|---|
predication | 110 | 5 | Store.predication | <<46 |
use_loop_index | 115 | 1 | Store.use_loop_index (f5) | <<51 |
source (VectorRegister) | 116 | 5 | Store.source (f7) | <<52 |
base (BaseAddressEncoding) | 121 | 2 | Store.base (f3) | <<57 |
feature_length_multiplier | 123 | 2 | Store.feature_length_multiplier (f4) | <<59 |
push_to_concat_register | 125 | 1 | Store.push_to_concat_register (f6) | <<61 |
存储范围:位 110..125(16 位)。有位测试~hasword & 0x22需要source+多一个字段; base 和 feature_length_multiplier 宽度在存储前由 < 4 范围检查确认。
表 C — VectorSlot.Load (EncodeBarnaCoreAddressHandlerVectorLoad @0x1e86e5c0)
Load 预测跨越 qword1/dword 边界;其余字段位于双字 (+16) 窗口中。
| 字段 | 捆绑钻头 | 宽度 | 原型场 | 放置 |
|---|---|---|---|---|
predication | 126 | 5 | Load.predication | 位 126,127(qword1)+ 128..130(dword) |
use_loop_index | 131 | 1 | Load.use_loop_index (f5) | 双字窗口 <<3 |
destination (VectorRegister) | 132 | 5 | Load.destination (f6) | 双字窗口 <<4 |
base (BaseAddressEncoding) | 137 | 2 | Load.base (f3) | 双字窗口 <<9 |
feature_length_multiplier | 139 | 2 | Load.feature_length_multiplier (f4) | 双字窗口 <<11 |
加载范围:位 126..140(15 位)。已位测试~hasword & 0x12。
表 D — VectorSlot.Result (EncodeBarnaCoreAddressHandlerVectorResult @0x1e86eb40)
| 字段 | 捆绑钻头 | 宽度 | 原型场 | 注释 |
|---|---|---|---|---|
predication | 141 | 5 | Result.predication | 双字窗口 <<13 |
| 结果有效 | 146 | 1 | (插槽存在) | 双字位 18(= byte18 位 2) |
which_destination | (子表格) | — | Result.which_destination (f2) | cmp 1/2里面的@0x1e86eb40选择EUP目标形式 |
destination (VectorRegister) | (合并中) | 5 | Result.destination (f4) | EUP 结果目标 vreg |
位 146(双字位 18)是 ApplyEupResultTargetWorkaround @0x1e8478a0 在 Jellyfish 芯片上重新定位的 EUP 结果存在位(它测试结果区域 — 双字位 13..17 = Result.predication,双字位 19..20 = 2 位以结果为目标的补丁)。
注意 — 存储/加载
base和Result.which_destination枚举值此处未解码。BaseAddressEncoding(2 位< 4检查的base字段)和VectorResultDestination(which_destination) 是共享的 JF-ISA 枚举,不是特定于地址处理程序的;上面的“字段位位置”是准确的,但值→名称名册未进行字节解码。 [信心:头寸高,价值表低——超出了这里的范围。]
3. 预测 — 5 位字段和条件枚举
用途
每个槽都带有一个 5 位预测字段,用于控制该槽是否在每次循环迭代时触发。该字段是单个打包字节:一个 4 位条件选择器加上一个 1 位极性。由于不存在的时隙预先填充有 Never (§1),因此预测字段也是时隙存在机制 - 没有单独的“时隙空”操作码。
编码
EncoderJf::EncodeBarnaCorePredication<T> 有六个相同的实例化(分支 @0x1e85ea00、存储 @0x1e86e3a0、加载 @0x1e86e920、结果 @0x1e86f020、ShiftMask @0x1e86f4a0、AluInstruction @0x1e86fc60)。每个计算:
// Models EncodeBarnaCorePredication<…> @0x1e85ea00.
// pred is a BarnaCorePredication proto: [+24] = condition (int32), [+28] = value (bool).
function EncodePredication(pred):
if not pred.has_predication():
return 0x0f // kAlwaysExecute (unset default)
if not (pred.has_condition() and pred.has_value()):
return error("Message's predication is invalid")
// byte-exact: pred5 = condition + ((16*value) ^ 0x10)
return pred.condition + ((16 * pred.value) ^ 0x10)
// value=1 -> (16 ^ 0x10) = 0 -> pred5 = condition (0x00..0x0f)
// value=0 -> ( 0 ^ 0x10) = 0x10 -> pred5 = 0x10 | condition (0x10..0x1f)等效于 pred5 = condition[3:0] | (~value)<<4:位 4 是 NOT(value),位 3..0 是条件 (0..15)。极性位反转条件测试 - 每个条件都有一个“execute-if”(0x00..0x0f)和一个“execute-unless”(0x10..0x1f)编码。
两个构造函数固定边界值。 MakeBarnaCorePredication(cond, value) @0x14169b20 写入 [+24] = cond、[+28] = value、[+16] |= 3(均为 has 位)。 Always() = Make(ALWAYS=15, value=1) → 15 + 0 = 0x0f(= kAlwaysExecute、.rodata @0xb834cf8)。 Never() = Make(ALWAYS=15, value=0) → 15 + 0x10 = 0x1f(= kNeverExecute、.rodata @0xb834cfc)。
注意 — 在对任何时隙进行编码之前,调度程序会使用
kNeverExecute预填充六个时隙预测。EncoderJf::EncodeBarnaCoreAddressHandlerBundle@0x1e86fd80将kNeverExecute掩码为 5 位,并将其复制到六个时隙预测字段中:位 6 (ShiftMask)、位 48 (Alu0)、位 79 (Alu1)、位 110(存储)、位 126(加载)、位 141(结果)— 从预填充存储验证(kNeverExecute<<6、<<48和 qword1<<15/<<46/<<62= 位79/110/126,并进入双字<<13= 位 141)。当前槽的编码器会覆盖其自己的字段。Branchpred(位 30)无预填充 — 仅当存在分支子表单时才写入。这是字节级证明,表明不存在的 BarnaCore 插槽是Never无操作,而不是不同的操作码。 [信心:已确认。]
表 E — BarnaCorePredication.Condition(4 位;EnumDescriptorProto @0xc017b98)
| 值 | 名称 |
|---|---|
| 0 | FIRST_ID |
| 1 | FIRST_ID_IN_FEATURE |
| 2 | NEW_FEATURE_ID |
| 3 | NEW_TOKEN_ID |
| 4 | NEW_SAMPLE |
| 5 | LAST_ID_IN_BATCH |
| 5 | ONLY_ID_IN_FEATURE_SAMPLE (别名值为 5) |
| 6 | FIRST_ID_IN_BATCH |
| 7 | NEW_TILE |
| 8 | COMPARE_FEATURE_ID (与 Common.compared_feature_id @13..17 相比) |
| 9 | REPEATED_TOKEN_FEATURE |
| 10 | FIRST_ITERATION |
| 11 | LAST_ITERATION |
| 12 | NEW_SAMPLE_OR_TILE_FOR_THE_SAME_ID |
| 13 | REPEATED_TILE_SAMPLE |
| 14 | NEW_FEATURE_OR_TOKEN_FOR_THE_SAME_ID |
| 15 | ALWAYS |
十七个名称超过十六个值:ONLY_ID_IN_FEATURE_SAMPLE 别名 LAST_ID_IN_BATCH(均为 5),证明 allow_alias。 ALWAYS = 15 是默认值。该集合是嵌入表迭代边界谓词字母表 - 硬件评估的“特征行/令牌/样本/平铺/迭代边界”条件,用于控制在嵌入收集/分散处理程序的每个循环迭代上触发哪些槽。
明白了——不要将其与
BARNACORE_CHANNEL_PREDICATION_*混淆。 该二进制文件还带有一个并行的 Pufferfish-Channel 预测枚举(BARNACORE_CHANNEL_PREDICATION_FIRST_ID、…NOT_NEW_SAMPLE等),并在名称(NOT_*变体)中添加了显式极性。这是 BCS 通道个性的枚举,而不是此处解码的 JF/DF 地址处理程序BarnaCorePredication.Condition— 后者通过 1 位value字段表示极性,而不是名称。 [置信度:已确认 - 两个枚举在二进制文件中都是不同的符号。]
4. 操作数 — 立即数和标量寄存器选择器
用途
ALU/存储/加载操作数要么命名标量寄存器,要么命名循环高级索引,要么命名立即文字。 Common 标头携带文字槽和标量寄存器选择器;每个操作数 indexed_* 布尔值选择操作数的寄存器索引是循环高级 BarnaCore-ID 还是直接寄存器。
编码 — 直接模型
Common 标头恰好有两个立即字段:捆绑位 149..164 处的 imm_0 (f11, uint32)、位 165..180 处的 imm_1 (f12, uint32) — 都是 16 位文字。引用立即数(而不是标量寄存器)的操作数通过 ProtoUtils::GetConstants<VectorAluYEncoding>(Y 操作数选择器映射,由操作数选择器值键控)→ YIsImm(u32 v, ImmSlot* slot) @0x14169c20 进行路由,它分配或重用 ImmSlot。
// Models YIsImm @0x14169c20 (simplified).
// ImmSlot layout: [+0] half-A (u16), [+2] half-B (u16), [+4] in-use flag, [+5] dual/32-bit flag.
function YIsImm(v, slot):
sel = GetConstants<VectorAluYEncoding>().lookup(v) // operand-selector value -> Y encoding
if sel found: return sel // operand is a register/selector, not an imm
if (v >> 16) != 0: // 32-bit literal: needs both halves of one slot
if slot.dual_flag != 1 and slot.in_use == 0:
slot.half_B = HIWORD(v); slot.flags = 0x0101; slot.half_A = v
return 26 // dual-slot Y-encoding
else: error("All IMM slots are occupied.")
else: // 16-bit literal: one half of one slot
h = LOWORD(v)
allocate h into a free half (in_use / dual_flag bookkeeping)
return 8 or 9 (or the zero-literal selector) // single 16-bit Y-encodingYIsImm 验证文字是否适合槽模型:16 位值占一个槽的一半;具有非零高位字的值占用一个槽的两半(dual 标志)。两个 16 位立即数可以共存(每个槽一个);当请求第三个不同的文字时,会触发“所有 IMM 插槽均已占用”错误。这是 Pufferfish BCS 4×16 位立即区域的 JF/DF 模拟 — 更窄(2 个槽),因为地址处理程序包是 23 个字节,而 BCS 包是 32 个字节。
表 F — 立即槽
| 字段 | 捆绑钻头 | 宽度 | 原型场 | 分配器 |
|---|---|---|---|---|
imm_0 | 149..164 | 16 | Common.imm_0(f11,uint32) | YIsImm @0x14169c20 |
imm_1 | 165..180 | 16 | Common.imm_1(f12,uint32) | YIsImm @0x14169c20 |
注意 — 编码器将完整的 16 位文字写入每个插槽(
YIsImm强制执行 16 位匹配)。这两个文字占用位 149..180,完全位于 184 位结构内。无论“硬件”立即字段是完整的 16 位还是更窄的子字段,都会被推断 — 编码端写入 16;没有发现解码端读取器可以交叉验证消耗的宽度。 [置信度:已确认该结构每个槽保留 16 位;推断硬件读取全部 16 个。]
编码 — 标量寄存器选择器
Common.vs0/vs1/vs2(字段 8/9/10,每个 2 位,捆绑位 24..29)在地址处理程序数据路径读取的四个物理标量源寄存器中进行选择。
表 G — BarnaCoreAddressHandlerScalarRegister(2 位;EnumDescriptorProto @0xc018caf)
| 值 | 名称 | 角色 |
|---|---|---|
| 0 | BARNA_CORE_ID_VMEM_ADDRESS | 嵌入行VMEM基础(聚集/分散dest/src指针) |
| 1 | GRADIENT_VMEM_ADDRESS | 梯度VMEM底座(后通散射源) |
| 2 | BARNA_CORE_ID_WEIGHT | 重量 ID 寄存器 |
| 3 | BARNA_CORE_ID_ARGUMENTS | 参数指针(描述符/元数据库) |
六个 indexed_* 布尔值(Common 字段 2..7,捆绑位 18..23:indexed_load_destination、indexed_store_source、indexed_alu_0_x、indexed_alu_0_destination、 indexed_alu_1_x、indexed_alu_1_destination) 选择每个向量操作数,其寄存器索引是循环高级 BarnaCore-ID 索引 (indexed = true) 还是直接寄存器。 compared_feature_id(f1,5 位,位 13..17)是 COMPARE_FEATURE_ID 谓词条件(§3 表 E 值 8)的操作数。
5. JF 与 DF — 标量槽超集
用途
Jellyfish 和 Dragonfish 发出相同23 字节帧和相同矢量槽;它们的区别仅在于每个标量控制通道的暴露量。龙鱼是表面比较丰富的。
编码
EncoderJf::EncodeBarnaCoreAddressHandlerScalarSlot @0x1e86f2c0 是辅助程序 …ScalarSlotHelper @0x1e86f2e0 的 jmp,它写入 Loop(位 0..5)、ShiftMask 预测(位6)、Push有位。 EncoderDf::EncodeBarnaCoreAddressHandlerScalarSlot @0x1e85e8a0 首先调用 JF 帮助程序(继承 Loop/ShiftMask/Push),然后添加仅 Dragonfish 的子形式:Branch 预测(位 30)、branch_type (位 36)、branch_target_pc(位 37..43)和 prog_end(位 44)。
因此,Dragonfish 地址处理程序包是 Jellyfish 地址处理程序包的超集:它在标量通道中添加了一个控制流分支 + 一个程序结束标记,Jellyfish 不会通过其独立帮助程序公开该标记。两者的帧宽度(23 字节)、Common 标头和五个向量时隙相同。
| 字段 | 捆绑钻头 | JF | DF | 编码器 |
|---|---|---|---|---|
Loop.loop_size_minus_one | 0..5 | Y | Y | …ScalarSlotHelper @0x1e86f2e0 |
ShiftMask.predication | 6..10 | Y | Y | …ScalarSlotHelper @0x1e86f2e0 |
Push(有位) | — | Y | Y | …ScalarSlotHelper @0x1e86f2e0 |
Branch.predication | 30..34 | – | Y | EncoderDf::…ScalarSlot @0x1e85e8a0 |
Branch.branch_type | 36 | – | Y | EncoderDf::…ScalarSlot @0x1e85e8a0 |
Branch.branch_target_pc | 37..43 | – | Y | EncoderDf::…ScalarSlot @0x1e85e8a0 |
prog_end | 44 | – | Y | EncoderDf::…ScalarSlot @0x1e85e8a0 |
我们还没有什么
VectorResultDestination(Result.which_destination, f2) 值表 — 字段位位置准确(结果编码器@0x1e86eb40内的cmp 1/2子形式选择器;结果有效位 @146;双字位 19..20 处的 2 位结果目标ApplyEupResultTargetWorkaround补丁),但值→名称名册未解码。BaseAddressEncoding(Store.base/Load.base,2位)值表 - 共享的JF-ISA枚举(< 4检查);值→名称名册不是特定于地址处理程序的,并且未在此处解码。- qword1 内合并的
VectorAluInstruction操作码/操作数位布局 —EncodeBarnaCoreAddressHandlerVectorAlu委托给EncoderJf::EncodeBundleInternal并通过掩码0xffffc000000fffff+ 移位进行合并0x29/0x20/0x10;合并形式的每个字段操作码/Vx/YSrc 着陆位置没有被隔离(地址处理程序特定的预测 + 通道是准确的;操作码主体是 JF ISA,一个单独的解码)。 - 解码端逆 - 在此版本中未找到对称
BarnaCoreAddressHandler*Decoder;编码端 184 位图是权威的,但未经独立读取器交叉验证(ApplyEupResultTargetWorkaround只读取结果区域)。 imm_0/imm_1的硬件宽度 — 编码器在每个槽写入完整的 16 位,但推断硬件是否消耗全部 16 位或较窄的子字段。
相关组件
| 名称 | 关系 |
|---|---|
BarnaCoreAddressHandlerBundleBits | 每个时隙编码器写入的 23 字节结构 |
EncoderJf / EncoderDf (jellyfish::isa) | JF/DF编码器开; DF 标量槽是 JF 超集 |
MakeBarnaCorePredication / Always / Never | 谓词构造函数固定 0x0f / 0x1f |
YIsImm / ProtoUtils::GetConstants<VectorAluYEncoding> | 立即操作数分配器 + Y 操作数选择器映射 |
ApplyEupResultTargetWorkaround | 唯一已知的阅读器;重用 23*N 步幅;修补 Jellyfish 上的结果区域 |
HardwareBundleBits | 持有kAlwaysExecute=0x0f(@0xb834cf8)、kNeverExecute=0x1f(@0xb834cfc)、kPredicateRegisterCount=0x0f(@0xb834cf4) |
交叉引用 {#cross-references}
- 概览 — BarnaCore,传统嵌入加速器; BCS / BCAH 个性分割和 C++
tpu::TpuSequencerType枚举(TC=0、BCS=1、BCAH=2;注意那里粗略的“16 B”编解码器组件标签 - 请参阅上面的 GOTCHA 以了解字节精确的 23 B 协调) - BCS 32 字节捆绑包 — Pufferfish BCS 音序器/通道包,本页与
BitCopy绝对位打包路径进行对比; BCS 4×16 位立即区域是 2 时隙模型的镜像 - BCS Scalar0/Scalar1 ISA — Pufferfish 双标量控制 + 内存操作码名册
- 合并 ALU 位布局 —
VectorResultDestination/BaseAddressEncoding,§2 表 B/C/D 中引用的共享 JF 向量 ALU 操作数枚举(但未进行值解码) - 退休证明 — BarnaCore → SparseCore 过渡; BCAH 是 v3 时代的个性,现已退休到 SparseCore
- 指数 — 第九部分 — SparseCore 和 BarnaCore / BarnaCore(旧版 v2–v4)
- 二进制:
extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(构建 ID89edbbe81c5b328a958fe628a9f2207d)