CycleTable 家族
本页中的每个偏移、值和地址都从
libtpu-0.0.40-cp314wheel 中的libtpu.so(BuildID md589edbbe81c5b328a958fe628a9f2207d)按字节精确读取。其他版本会不同。所有.rodata地址都是虚拟地址;对该二进制而言,.rodataVMA == 文件偏移(section[11]位于0x84a0000),而.textVMA == 文件偏移。
摘要
xla::jellyfish::CycleTable 是 TensorCore 成本模型中逐代吞吐量半边的抽象基类。它唯一的职责是把一个周期类 — 一个不透明的 CycleTable::Instruction enum 值,而不是 LLO opcode — 翻译成该类占用的最慢功能单元的 bundle-issue 周期成本。重新实现者应把它想象成两个协作对象:CycleTable(本家族)回答“cycle-class I 要花多少 issue cycles,以及它阻塞哪条 resource lane?”,而逐代 Performance 网格则是 CycleTable 实际读取的扁平 .rodata 烘焙数组。CycleTable 自身不拥有任何周期数字;它在 +0x10 持有一个 Performance* 并对其索引。
每个 tpu::TpuVersion 恰好有一个子类。六个已注册工厂(TpuVersion 0..5)折叠为四种不同读取策略:扁平 offset-LUT(JfCycleTable,由两个最老的代共享),以及三种 switch-over-Performance::GetResourceUsage 形式(PfCycleTable、VfCycleTable,以及 helper 包裹的 GlcCycleTable/GfcCycleTable)。cycle-class 枚举是所有代共享的稠密 0x00..0x20(33 个值);每代会对一个子集定价,其余返回默认 1 cycle。
本页是该家族的框架参考:它给出类层级、注册/分派路径、33 值 cycle-class enum 的结构,以及该家族如何位于 Performance 网格和 MXU latency 保留矩阵旁边。逐代读取路径和烘焙常量位于 JfCycleTable、VfCycleTable 和 Per-Opcode Cycle Constants。
重新实现者必须遵守的契约:
- 每个
TpuVersion一个CycleTable,由工厂 registry 选择,而不是由if链选择。CycleTable::Create(const Target&)读取target.tpu_version()并调用已注册 lambda;未注册版本是 fatal。 Instruction参数是 cycle class,不是 opcode。 LLO opcodes 先由CycleTableInstruction(LloInstruction*)折叠为 33 个 class 之一;那里只分类 MXU matmul/latch/matprep opcodes。GetCyclesForThroughput(I)是 bundle-issue 吞吐量,不是依赖延迟。 延迟轴是单独的对象(LatencyTable*);JfCycleTablevtable 没有 latency slot。GetResource(I)命名该 class 阻塞的 lane。 调度器把(double)cycles加到ResourceVector[GetResource(I)];一个 bundle 的贡献是其槽位 lane 成本的最大值,而不是总和。- 超越函数由标量虚拟 override 定价(
EstimateSinCosCost、EstimateTanCost),而不是由 cycle-class LUT 定价。
| 抽象基类 | xla::jellyfish::CycleTable(纯虚 GetCyclesForThroughput) |
JfCycleTable vtable | 0x21c1ffb8 — slots: dtor pair, GetCyclesForThroughput @ 0x1c89dce0, EstimateSinCosCost, EstimateTanCost |
| 工厂 | CycleTable::Create(const Target&) @ 0x1c89cc00 — 按 target.tpu_version() 分派 |
| Sibling 工厂 | LatencyTable::Create(TpuVersion) @ 0x1c89fba0 — ordinal-indexed AnyInvocable vector,而非 hash registry |
| 注册 | _GLOBAL__sub_I_cycle_table.cc @ 0x21353460 — 6 × FunctionRegistry::Register(version, λ) |
| Cycle-class enum | CycleTable::Instruction — 稠密 0x00..0x20(33 个值);逐代定价子集 |
| Opcode → class | CycleTableInstruction(LloInstruction*) @ 0x1c89ca80 — 仅 MXU 段 |
| 吞吐量访问器 | GetCyclesForThroughput(Instruction) — 逐代虚函数;默认 1 |
| Resource 访问器 | CycleTable::GetResource(Instruction) @ 0x1c89ce20 — 扁平 LUT dword_B438AEC |
| 底层网格 | CycleTable+0x10 持有的逐代 Performance 对象 |
CycleTable 是什么
成本模型被拆成两个严格分离的层级(这个拆分是该子系统的核心设计事实):
CycleTable— 一个很薄的逐代虚分派器,以周期类为键。它回答关于 classI的两个问题:GetCyclesForThroughput(I)(issue cycles)和GetResource(I)(哪个功能单元 lane)。它不存储自己的周期数字;它拥有一个Performance*。Performance— 逐代扁平烘焙周期常量数组,宽0xe00字节,查询零成本(Performance[byte_offset])。CycleTable是唯一知道如何把 class 映射到字节偏移(JF/DF)或 instruction/resource 对(PF 及以后)的东西。
吞吐量周期(本家族)和依赖延迟(LatencyTable* 家族)最终都读取同一个逐代 Performance 对象;它们只是其上的不同访问方法(GetCyclesForThroughput/GetResourceUsage vs GetLatency/GetLatencyBetween)。JfCycleTable vtable 完全没有 GetLatency slot — 它的 slots 是吞吐量(+0x10)、EstimateSinCos(+0x18)、EstimateTan(+0x20)以及两个 device-detail 访问器。在 Jellyfish/Dragonfish 上,延迟轴完全由单独的 LatencyTableJellyfish 提供;见 bundle-aware cost。
重新实现者不应尝试合并这两个层级。Performance 网格是逐代私有数据;CycleTable 是作用于其上的逐代私有访问模式。33-class enum 是它们之间共享的词汇表。
类层级和逐版本分派
xla::jellyfish::CycleTable (abstract base; JfCycleTable vtable @ 0x21c1ffb8)
|
+----------+-----------+-----------+-------------+--------------+
| | | | | |
JfCycleTable (TpuVersion 0 + 1) PfCycleTable VfCycleTable GlcCycleTable GfcCycleTable
flat offset-LUT (TpuVersion 2) (TpuVersion 3) (TpuVersion 4) (TpuVersion 5)
jellyfish v2 / dragonfish v3 pufferfish v4 viperfish v5 ghostlite v6L 6acc60406 (TPU7x)六个工厂由 cycle_table.cc 静态初始化器(_GLOBAL__sub_I_cycle_table.cc @ 0x21353460)注册一次,每个都是一个 FunctionRegistry<TpuVersion, unique_ptr<CycleTable>(const Target&)> 条目。选择发生在 CycleTable::Create @ 0x1c89cc00,它从 Target 读取版本、查找 lambda 并调用它;缺失注册会 fatal log("No cycle table registered for platform: ",cycle_table.cc:960)。
TpuVersion | 代号 | 子类 | GetCyclesForThroughput | 读取策略 |
|---|---|---|---|---|
| 0 | jellyfish (v2) | JfCycleTable | 0x1c89dce0 | 扁平 offset-LUT(kUnusedRegisterJfCycleTable) |
| 1 | dragonfish (v3) | JfCycleTable | 0x1c89dce0 | 扁平 offset-LUT(kUnusedRegisterDfCycleTable) |
| 2 | pufferfish (v4) | PfCycleTable | 0x1c89de60 | switch → GetResourceUsage(instr,res) |
| 3 | viperfish (v5) | VfCycleTable | 0x1c89e2c0 | switch → GetResourceUsage(instr,res) |
| 4 | ghostlite (v6 lite) | GlcCycleTable | 0x1c89e980 (wrapper) | helper 0x1c89ed20 + CHECK(ok) |
| 5 | 6acc60406 (TPU7x) | GfcCycleTable | 0x1c89f060 (wrapper) | helper 0x1c89f400 + CHECK(ok) |
注意 —
TpuVersion0 和 1 共享一个类。 jellyfish (v0) 和 dragonfish (v1) 工厂都会产生一个JfCycleTable— 两个 registry 条目分别绑定符号kUnusedRegisterJfCycleTable和kUnusedRegisterDfCycleTable,但都绑定到同一个JfCycleTable工厂 lambda。两者都在同一个吞吐量 offset-LUT 上读取GetCyclesForThroughput@0x1c89dce0;这两代只在各自Performance网格中不同,而不同的 cells 并非吞吐量 LUT 目标 — 因此 JF 和 DF 的GetCyclesForThroughput相同。见 JfCycleTable。
后两代(Glc、Gfc)包裹一个返回 absl::Status 风格结果的 …Helper;公开的 GetCyclesForThroughput 调用 helper 并在返回周期整数前 CHECK 成功(MakeCheckFailString(..., "cycles is OK"),fatal at cycle_table.cc:817)。重新实现可以把它展平成直接返回;wrapper 只是为了把“不可调度 class”暴露为 fatal,而不是静默默认值。
Sibling 工厂 — LatencyTable::Create(TpuVersion) {#the-sibling-factory--latencytablecreatetpuversion}
吞吐量半边(CycleTable)和依赖延迟半边(LatencyTable)是并行的逐代家族,但它们的工厂使用两种结构不同的分派机制,重新实现者不能假设一个镜像另一个。
CycleTable::Create(const Target&) @ 0x1c89cc00 以 FunctionRegistry<TpuVersion, …>(hash map)为键。LatencyTable::Create(tpu::TpuVersion) @ 0x1c89fba0 则以按版本 ordinal 索引的稠密 inlined-vector为键 — 没有 cmp $0xN switch,也没有 hash lookup。ordinal 会按 vector size 做边界检查,然后直接调用 version 第 version 个 32 字节 slot 中 byte offset +0x18 处存储的 absl::AnyInvocable 工厂:
// xla::jellyfish::LatencyTable::Create @ 0x1c89fba0 (decompiled, exact shape)
unique_ptr<LatencyTable> LatencyTable::Create(tpu::TpuVersion v) {
Vector *reg = registry; // @ 0x225799f8, file-local inlined_vector
if (reg == nullptr)
LogFatal("registry", /*latency_table.cc:0x78*/); // "registry" non-null CHECK
if ((int64_t)v < 0 || (size_t)v >= reg->size()) // signed + size bound, both fatal
LogFatal(/*latency_table.cc:0x7a / 0x7b*/);
void *entry = reg->data() + ((size_t)v << 5); // 32-byte AnyInvocable stride
void (*fn)() = *(void**)(entry + 0x18); // stored factory pointer
if (fn == nullptr)
LogFatal("registered", /*latency_table.cc:0x7c*/);
return fn(entry); // call *%rax @ 0x1c89fc0f
}因此 version→ctor 绑定在 Create 内部不可见 — 它由五个独立 translation-unit 初始化器在静态初始化时写入,每个都调用 LatencyTable::Register(version, AnyInvocable) @ 0x1c89fac0(该函数把 vector Resize 到 version+1,并把 invoker 存到 slot +0x18)。分派尾部是这五个初始化器的并集:
| Ordinal | 代号 | Initializer (.text.startup) | Register(v, λ) arg | Factory invoker λ | 具体 ctor (new size) |
|---|---|---|---|---|---|
| 0 | jellyfish (v2) | _GLOBAL__sub_I_latency_table_jf.cc @ 0x21353860 | mov $0x0,%edi @ 0x21353885 | LocalInvoker<jellyfish::$_0> @ 0x1c8a1280 | LatencyTableJellyfish::C1 @ 0x1c8a0c20 (new 0x58) |
| 1 | dragonfish (v3) | _GLOBAL__sub_I_latency_table_jf.cc @ 0x21353860 | mov $0x1,%edi @ 0x213538a9 | LocalInvoker<jellyfish::$_1> @ 0x1c8a12c0 | LatencyTableJellyfish::C1 @ 0x1c8a0c20 (new 0x58) |
| 2 | pufferfish (v4) | _GLOBAL__sub_I_latency_table_pf.cc @ 0x213538d0 | mov $0x2,%edi @ 0x213538f3 | LocalInvoker<pufferfish::$_0> @ 0x1c8a31c0 | LatencyTablePufferfish::C1 @ 0x1c8a1960 (new 0x1e0) |
| 3 | viperfish (v5) | _GLOBAL__sub_I_latency_table_vf.cc @ 0x21353920 | mov $0x3,%edi @ 0x21353943 | LocalInvoker<viperfish::$_0> @ 0x1c8a5280 | LatencyTableViperfish::C1 @ 0x1c8a3f20 (new 0x1e0) |
| 4 | ghostlite (v6 lite) | _GLOBAL__sub_I_latency_table_gl.cc @ 0x21353970 | mov $0x4,%edi @ 0x21353993 | LocalInvoker<ghostlite::$_0> @ 0x1c8b28e0 | LatencyTableGhostlite::C1 @ 0x1c8b0c00 (new 0x1e0) |
| 5 | 6acc60406 (TPU7x) | _GLOBAL__sub_I_latency_table_gf.cc @ 0x213539c0 | mov $0x5,%edi @ 0x213539e3 | GF invoker λ @ 0x1c8bb180 (symbol-coalesced) | GF LatencyTable ctor @ 0x1c8b9520 (new 0x1e0) |
注意 —
LatencyTable和CycleTable工厂不是同一台机器。CycleTable::Create使用FunctionRegistryhash map 并通过 lambda lookup 分派;LatencyTable::Create使用扁平 ordinal-indexedinlined_vector<AnyInvocable, 8>(文件局部registry@0x225799f8),并通过registry[version](entry)(call *0x18(%rdi,version<<5))分派。“没有注册工厂”的失败模式也不同:CycleTable记录"No cycle table registered for platform: ";LatencyTable::Create则发出三个不同的 fatal CHECK(latency_table.cc:0x78处registry非空,0x7a/0x7b处 ordinal in-bounds,0x7c处 slot 非空)。重新实现者可以把两者都折叠为一个 ordinal-keyed table,但必须保留间接调用前的 bounds CHECK。注意 — JF 和 DF 与 cycle 侧一样共享
LatencyTableJellyfish。 Ordinals 0 和 1 注册两个不同 lambda(jellyfish::$_0@0x1c8a1280、jellyfish::$_1@0x1c8a12c0),但两者都new (0x58)并 tail-call 同一个 ctorLatencyTableJellyfish::C1@0x1c8a0c20。两个 lambda 的存在只是因为 JF 和 DF 被注册为不同 ordinal;构造出的对象类型相同。这镜像了上方“两个 gens 都用JfCycleTable”的事实。注意 JF 对象是0x58字节,而 PF/VF/GL/GF 对象都是0x1e0字节 — 后几代会内联携带逐MatmulModifier/VlxmrModifierMXU-latency maps。怪癖 — GF(ordinal 5)工厂和 ctor 的符号被 strip。 不同于其他五个分支,GF invoker(
0x1c8bb180)和 GFLatencyTablector(0x1c8b9520)在nm中都没有自己的解混淆符号;两者都被折叠到相邻的raw_hash_set<…VlxmrModifier…>::find符号下(分别在+0x1d80和+0x120)。GF 身份仍然由三种字节锚定:(1)latency_table_gf.cc的初始化器用这个精确 invoker 指针Registerordinal5(lea 0x1c8bb180@0x213539c9);(2) invoker 执行new (0x1e0)并调用0x1c8b9520;(3)0x1c8b9520调用LatencyTable基类 ctor(0x1c89f800)、把0x1e0字节对象体清零、安装自己的一对 vtables(0x21c20930+0x10到[obj],+0x48到[obj+0x18]),并加载 ghostliteGetSharedMxuLatencysingleton(0x22579a70)—VlxmrModifier(variable-latency MXU modifier)类型和gfTU 名称共同标记它是 GF/TPU7x 代。符号合并是 linker ICF 产物,不是缺失函数。注意 — 基类 vs 子类
LatencyTable。xla::jellyfish::LatencyTable是抽象基类(C2ctor @0x1c89f800,提供LatencyBetween@0x1c89f820、IsTrueDependencyBetween、HasSetPermutePatternReservation等)。上面的每个逐代分支都继承它:JF 分支在jellyfishnamespace,PF 在pufferfish,VF 在viperfish,GL/GF 在ghostlite(GF ctor 复用 ghostlite shared MXU-latency table)。基类LatencyTable::Create/Register/registry三件套位于jellyfishnamespace,并由所有代共享。
Cycle-Class 枚举(CycleTable::Instruction)
CycleTable::Instruction 是稠密 enum 0x00..0x20(33 个值)。它不是 LLO opcode,也不是 Performance/GhPerf::Instruction 网格索引 — 它是 MXU 和 vector 功能行为的粗粒度分桶,逐字共享于全部六代。即使周期整数不同,每个 class 扮演的角色在各代之间保持稳定。
| Class | 角色 | JF/DF |
|---|---|---|
0x00 | Vector matprep, bf16 | 8 |
0x01-0x04 | matprep variants(bf16/fp8 family) | default 1 |
0x05 | Latch / push gains, bf16 | 8 |
0x06 | Latch, int4 | default 1 |
0x07,0x08 | 6acc60406 new latch paths(latch_mode 48/50) | default 1 |
0x09 | Latch, fp8 | default 1 |
0x0a | PushGainsS4 — PF/VF 上 fatal("Unsupported PushGainsS4.",cycle_table.cc:682) | default 1 |
0x0b | Transposed bf16 latch | 8 |
0x0c | Transposed int8 latch | default 1 |
0x0d,0x0e | 6acc60406 transposed latch(latch_mode 49/51) | default 1 |
0x0f | Transposed fp8 latch | default 1 |
0x10 | transposed PushGainsS4 — PF/VF 上 fatal,与 0x0a 使用同一 "Unsupported PushGainsS4." 字符串 | default 1 |
0x11 | Vector EUP class | default 1 |
0x12,0x13 | XLU rotate in/out (RotIn/RotOut) | 1 |
0x14 | Shuffle / permute | 1 |
0x15,0x16 | Broadcast / reduce | 1 |
0x17 | Matrix-result read (TC) | 8 |
0x18 | Read/write transpose register | 1 |
0x19 | Cross-lane reduction | 1 |
0x1a | Lane comparison / EUP edge | 1 |
0x1b | Matrix-result read, primary | 8 |
0x1c | Matrix-result read, secondary | 8 |
0x1d,0x1e | EUP unary primary/secondary | default 1 |
0x1f | Matrix-result read | 8 |
0x20 | Transcendental class(vector ALU "any") | 1 |
怪癖 — “33 classes” vs “16 priced”。 enum 覆盖
0x00..0x20,但JfCycleTable只对其中 16 个定价(其余落入默认1)。定价集合由字面量 mask0x19FFC0821固定(见 JfCycleTable);后续代会对额外 bf16/fp8 latch 和 matprep 变体定价。上方 JF/DF 列对七个 MXU classes 显示8,对九个已定价 vector classes 显示1;"default 1" 标记 JF mask 留作未定价的 classes。角色标签跨代稳定 — 重新实现者只需移植一次 role-to-class map,并按代重新定价。
将 opcodes 折叠为 classes — CycleTableInstruction
xla::jellyfish::CycleTableInstruction(LloInstruction*) @ 0x1c89ca80 是 MXU cycle classes 的唯一生产者。它恰好分类两个 opcode 段,对其他任何东西都是 fatal:
// xla::jellyfish::CycleTableInstruction @ 0x1c89ca80 (decompiled, exact shape)
uint32_t CycleTableInstruction(const LloInstruction *insn) {
uint32_t op = insn->opcode;
if ((uint16_t)(op - 141) <= 9) { // opcodes 141..150 = matmul/latch band
uint8_t lm = insn->latch_mode();
if (lm >= 0x34 || !bittest64(0xF000003FFFC3F, lm))
LogFatal("Unsupported gain latch mode ", /*cycle_table.cc:431*/);
return unk_B4389F4[lm]; // latchLUT @ 0xb4389f4, 52 × int32
}
if ((uint16_t)(op - 155) <= 0xA) { // opcodes 155..165 = matprep/matpush band
uint8_t f = insn->matmul_data_format() - 1;
if (f >= 0xA)
LogFatal("Unsupported matmul data format ", /*cycle_table.cc:464*/);
return unk_B438AC4[f]; // fmtLUT @ 0xb438ac4, indices 0..9 read
}
LogFatal("Unsupported instruction ", /*cycle_table.cc:470*/);
}两个 .rodata 查找表把 MXU modifier 转成 cycle class:
| 表 | 地址 | 形状 | 映射 |
|---|---|---|---|
latchLUT (unk_B4389F4) | 0xb4389f4 | 52 × int32,valid mask 0xF000003FFFC3F | GainLatchMode → Instruction |
fmtLUT (unk_B438AC4) | 0xb438ac4 | int32[],按 matmul_data_format()-1 索引;classifier 只读取 indices 0..9(< 0xA guard) | MatmulDataFormat → Instruction |
latch LUT(mask bits 已与 raw table 验证):0x00/0x02/0x04 → 5,0x01/0x03/0x05 → 11,0x0a → 12,0x0b/0x0e/0x10 → 6,0x0c → 9,0x0d → 15,0x0f/0x11 → 12,0x12/0x14/0x16/0x18 → 9,0x13/0x15/0x17/0x19 → 15,0x30 → 7,0x31 → 13,0x32 → 8,0x33 → 14。fmt LUT(index = format-1)读取 [0,1,1,1,4,4,4,4,2,3,1];< 0xA guard 意味着只有 indices 0..9 可达,即 fmt 1 → 0,fmt 2/3/4 → 1,fmt 5/6/7/8 → 4,fmt 9 → 2,fmt 10 → 3。第 11 个条目(fmt 11 → 1)存在于 .rodata 中,但该 classifier 会把它作为 fatal "Unsupported matmul data format "(cycle_table.cc:464)拒绝;它只由后续代路径读取。CycleTableInstruction 本身与代无关 — 同一个 classifier 为每一代产生 MXU cycle classes。vector/EUP/matrix-result classes(0x11..0x20)由非 MXU emitter 路径产生,而不是由 CycleTableInstruction 产生。
注意 — format LUT 比 classifier 读取的更宽。
matmul_data_format()-1有效性检查是< 0xA,因此CycleTableInstruction只读取前 10 个 fmt 条目(formats 1..10)。第 11 及之后的 format 值(packed int8/int4)由后续代Performance/MxuLatency路径使用,并在 matmul mode modifiers 中记录;共享 classifier 会把它们作为 fatal 拒绝。
Resource 侧 — CycleTable::GetResource
CycleTable::GetResource(Instruction) @ 0x1c89ce20 是单个扁平查找,由所有代共享:
// xla::jellyfish::CycleTable::GetResource @ 0x1c89ce20 (decompiled, exact)
int GetResource(int instruction) {
return dword_B438AEC[instruction]; // resLUT @ 0xb438aec, 33 × int32
}返回值直接是逐 op ResourceVector 中的 slot index — AccumulateInstructionUsage 执行 ResourceVector::Acc(GetResource(I), (double)GetCyclesForThroughput(I)),而 ResourceVector::Acc(0x1c89adc0)是 [rdi + Resource*8] += cycles,并带有 cmp esi, 0x17 bound(23 slots)。JF/DF resource LUT 只发出值 0..6 — 23-slot accumulator 的 MXU/vector 头部(见 resource enum):
GetResource 值 | ResourceVector slot | 名称 | JF/DF 占用 classes |
|---|---|---|---|
| 0 | R[0] | Matpush | 0x05..0x10(latch band) |
| 1 | R[1] | Matmul | 0x00..0x04(matprep band) |
| 2 | R[2] | Xlu | 0x17, 0x1b..0x1f(matrix-result / cross-lane) |
| 3 | R[3] | VectorAlu0 | 0x14 |
| 4 | R[4] | VectorAlu1 | 0x12, 0x13 |
| 5 | R[5] | VectorAluAny | 0x15, 0x16, 0x19, 0x20 |
| 6 | R[6] | VectorEup | 0x11, 0x18, 0x1a |
这是成本模型建模resource conflict 的机制:映射到同一 lane 的两个 class 会相加(在该单元上顺序执行);映射到不同 lane 的两个 class 会重叠(调度器取一个 bundle 内各 lane 的最大值)。ResourceVector enum 名称是来自符号表的绑定;每个 R[k] 名称下的语义微端口映射是一种解释。
这与 Performance 和 MxuLatency 的关系
| 表家族 | 它回答什么 | 访问器 | 页面 |
|---|---|---|---|
| CycleTable(本页) | 一个 cycle class 的 issue cycles + lane | GetCyclesForThroughput, GetResource | 此处 |
| Performance | CycleTable 读取的逐代烘焙周期网格 | GetResourceUsage(instr,res), GetLatency | 概览 |
| MxuLatency | 逐 (MatmulModifier × Resource) matmul/matprep cycles | GetResourceUsage(keyed map) | 概览 |
LatencyTable* | read-after-write 依赖延迟 | GetLatency, GetLatencyBetween | bundle-aware cost |
清晰的读法是:CycleTable 是索引逻辑;Performance 网格是数据;当简单的 (instruction, resource) lookup 过于粗糙时(matmul 成本取决于 (format, transpose-flag, MSR/MRB target),而不是单个逐 opcode 常量),MxuLatency map 是逐代的覆盖。LatencyTable* 是正交轴,调度器通过逐 op ResourceVector 将它与吞吐量 cycles 组合。具体的逐代整数 — 包括七个 JF/DF 8-cycle MXU cells,以及 matmul base-latency clusters(bf16/F32 = 131 / 192 / 212,fp8 = 114-115 / 192 / 204,在 Vf/Gl/Gf 上针对逐代 Performance latency arrays 解析;注意这些是 op base latencies,不是 MxuLatencyTable 返回的小 per-resource throughput cells,且 GL/GF matmul_latencies_ map 携带 sibling pair 192/182 (GL) 和 211/204 (GF) — 见 MXU Latency: GL/GF)— 都列在 Per-Opcode Cycle Constants 中。
交叉引用
- JfCycleTable — 扁平 offset-LUT 读取路径、16-of-33 定价子集,以及最老几代的 7 列 resource 命名。
- VfCycleTable — Viperfish
switch-over-GetResourceUsage读取路径。 - Per-Opcode Cycle Constants — 按 gen/engine 分组的烘焙
.rodatacycle tables,以及 bundle-latency 成本模型如何求和。 - Performance Family Overview — CycleTable 索引的逐代
Performance<gen>网格。 - MXU Latency Overview — 覆盖简单 matmul cells 的逐
(MatmulModifier × Resource)保留矩阵。 - Resource Enum — JF/DF resource LUT 发出的 23-slot
ResourceVector头部R[0]..R[6]。 - Bundle-Aware Cost — 逐 op 吞吐量 cycles 和逐 op resource vectors 如何组合成 bundle issue cost。
- Bundle Model Overview — 成本模型归属 cycles 的 VLIW bundle 层。
- Binary:
extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(build-id89edbbe81c5b328a958fe628a9f2207d) - 索引条目: Part VII — Cost & Latency Model / CycleTable — 返回索引