性能:GL (GhPerf 476×31)
本页所有地址均适用于
libtpu-0.0.40-cp314wheel 中的libtpu.so(构建libtpu_lts_20260413_b_RC00,BuildID md589edbbe81c5b328a958fe628a9f2207d)。该二进制未剥离符号,每个符号都是反修饰后的 C++ 名称。.text/.rodataVMA == 文件偏移;.data.rel.roVMA − 0x200000 == 文件偏移。其他版本会不同。
摘要
xla::ghostlite::GhostlitePerformance 是 performance-overview 中所述网格族 Performance 对象的 Ghostlite(TpuVer 4,v6e)实例。它是内部昵称为 GhPerf 的两个 GhostlitePerformance 构造函数之一:本页记录具名的 v6e 变体,另一个是 performance-gf-ghperf 中的误符号化 v7(6acc60406)变体。它以两种方式为每条 LLO 指令定价:一个按 GhostlitePerformance::Instruction 索引的扁平延迟数组,由 GetLatency 读取以设置 true-dependency edge 的深度;以及一个二维 Instruction × Resource 占用网格,由 GetResourceUsage(instr, res) 读取,用来计费该指令占用每个 intra-op 微流水线端口的周期数。该网格是 libtpu 中类似 LLVM SchedMachineModel ProcResource/WriteRes 表的结构,是通过解码填充它的构造函数重建出来的。
Ghostlite 网格为 476 × 31:476 个指令行(v6e GhostlitePerformance::Instruction 基数)和 31 个资源列(GhostlitePerformance::Resource,EUP/Xlu/MXU-result 微流水线端口)。对象布局、带两次边界检查和 24 字节行跨度的 GetResourceUsage 读取路径,以及资源数量 31,都与 Viperfish 网格和 GF(6acc60406)孪生共享;构造函数 _ZN3xla9ghostlite20GhostlitePerformanceC1Ev @0x1c8cbc80(唯一仍带清晰符号的 GhPerf 构造函数)以及每个单元格整数是 v6e 特有的。该网格不为 MXU matmul/matpush reservation 定价;那是单独的 MxuLatencyTable(mxu-latency-gl)。GhPerf 网格和 MxuLatencyTable 在按 dtype 的吞吐量级({4 bf16 / 8 fp8})上一致,但回答不同问题,并位于所有者 GlcCycleTable 的不同子对象中。
本页记录 Ghostlite 网格:构造函数构建的对象;字节完全相同的 GetResourceUsage/GetLatency 读取路径;LLO opcode 如何通过 GetGhostliteInstruction @0x1c8b1740 分类器及其 MXU/permute/transpose latch-mode fan-out 到达网格行;按占用指令类描述而不是逐单元格转录的 31 个资源列;卷积成本模型作为其 R[2] 项读取的 Xlu/matrix-result deposit 列(GL res 0x0f);以及约 344 个未定价行采用的 0xff 默认回退路径。已填充行的完整逐单元格转储按区段描述,不在此全文转录。
对于重新实现,契约是:
GhostlitePerformance对象布局:堆延迟数组(new 0x770,476 int32,memset0xff)和堆二维网格(new 0x2ca0,476 × 24 字节std::vector<int>),每行是 31 宽的零初始化 vector。GetResourceUsage(instr, res)和GetLatency(instr)读取路径,包括两次边界检查(外层在[this+0x20],内层在[row+8])和 24 字节行跨度。- opcode → row 分类器
GetGhostliteInstruction:二分搜索 WORD 重映射表,加上把一个 opcode fan-out 为多行的显式 MXU/permute/transpose/compare switch。 - 按区段划分的 31 个资源列,以及
GetXluPathReservation作为 convR[2]周期读取的 Xlu/matrix-result deposit 列 GL res0x0f(每个 matrix-result op 的 cell= 4)。 0xff默认回退:约 344 个未定价行保留 memset sentinel,并通过单独的CycleTable路径定价,而不是由该网格定价。
| 类 | xla::ghostlite::GhostlitePerformance(内部称 "GhPerf",v6e 变体) |
| 构造函数 | GhostlitePerformanceC1Ev @0x1c8cbc80(31284 B;清晰符号;latency new 0x770,grid new 0x2ca0) |
| 读取路径 | GhostlitePerformance::GetResourceUsage @0x1c8d3700;GetLatency @0x1c8d36e0;GetResources @0x1c8d36c0 |
| 网格形状 | 476 行(Instruction,计数 0x1dc)× 31 列(Resource);132 行中共有 358 个已填充单元格 |
| 延迟数组 | new 0x770 = 1904 B = 476 int32;memset 0xff(约 344 个未定价行默认 255) |
| 行分类器 | ghostlite::GetGhostliteInstruction @0x1c8b1740(WORD 重映射 + MXU latch-mode fan-out) |
| Xlu deposit 列 | GL res 0x0f (15);对每个 matrix-result/cmem/transpose-result op,cell = 4 |
| kResources 顺序 | @0xb43cdc4(31 字节,包含 {0..30} 全部;0x0f 最后) |
| 所有者 CycleTable | GlcCycleTable @0x1c89e7e0 — 网格位于 this+0x10,MxuLatencyTable 位于 this+0x18 |
| 源文件 | …/jellyfish/target/ghostlite/latency_table_gl.cc(CHECK/LogFatal 锚点) |
Performance 对象
目的
构造函数构建两个堆分配,并且只填充已定价单元格。读取路径触及的一切(延迟数组、其计数、网格指针、外层计数以及每行的 std::vector<int> 头部)都由 GhostlitePerformanceC1Ev @0x1c8cbc80 布局。未定价行被有意留在 sentinel 值,使下游调用者能区分“此 op 不由网格定价”和“此 op 持有零周期”。
结构
该对象是 Pufferfish、Viperfish 和两个 GhPerf 变体共享的网格族布局;只有宽度不同(Ghostlite 使用 476 行 / 31 列):
struct GhostlitePerformance { // built by GhostlitePerformanceC1Ev @0x1c8cbc80
int32* latency; // +0x00 ; new 0x770 (476 int32), memset 0xff
u64 latency_size; // +0x08 ; = 0x1dc (476) — GetLatency bound
u64 latency_cap; // +0x10 ; = 0x1dc (476)
vector<int>* grid; // +0x18 ; new 0x2ca0 (476 × 24-byte vector<int>)
u64 grid_outer_count; // +0x20 ; = 0x1dc (476) — GetResourceUsage outer bound
u64 grid_outer_cap; // +0x28 ; = 0x1dc (476)
// each grid row (24-byte std::vector<int>): { int* data (new 0x7c = 31 int32, zero-init),
// size = 0x1f (31), cap = 0x1f (31) }
};
```text
构造函数序言在 `@0x1c8cbc80` 处经字节确认:
```c
function GhostlitePerformanceC1Ev(this): // @0x1c8cbc80
this.latency = new(0x770) // @0x1c8cbc96 — 1904 B = 476 int32
this.latency_cap = 0x1dc // [this+0x10] = 476
memset(this.latency, 0xff, 0x770) // @0x1c8cbcb3 — sentinel fill
this.latency_size = 0x1dc // [this+0x08] = 476
this.grid = new(0x2ca0) // @0x1c8cbcd2 — 12192 B = 476 × 24
this.grid_outer_cap = 0x1dc // [this+0x28] = 476
for r in 0 .. 475: // loop bound r15 == 0x2cb0 (0x18 + 476*24)
row.data = new(0x7c) // @0x1c8cbcf8 — 124 B = 31 int32
zero(row.data, 0x7c) // vxorps + vmovups ×4 (@0x1c8cbd02..)
row.size = 0x1f ; row.cap = 0x1f // [row+8]=[row+0x10]=31
this.grid_outer_count = 0x1dc // [this+0x20] = 476
// ... then 834 DWORD-immediate stores: 476 latency entries + 358 grid cells头部设置完成后,主体正好发出 834 个 mov DWORD PTR [addr], imm 存储:476 个写入每个延迟槽(前三个 latency[0]=1、latency[1]=1、latency[2]=2 在 @0x1c8cbd50/64/79 写入 [this+0x00]),其余 358 个写入已填充网格单元格。存储计数恰为 476 + 358,这是每个存储都已分类的完整性检查。
怪异点 — 位于
@0x1c8cbc80的 GL 构造函数带有清晰符号_ZN3xla9ghostlite20GhostlitePerformanceC1Ev,但 GF(6acc60406)GhPerf 构造函数@0x1c8d3740在二进制中被误符号化(带占位符号sub_1C8D3740);它是GfcCycleTable分配的变体,结构上是同一个GhostlitePerformance布局(31 宽行),但指令集为 465 行而不是 476 行。两个构造函数不同,单元格值不同,基础延迟也不同(GL EUP/transcendental 为 192/182,GF 为 212/204),不是共享实例。见performance-gf-ghperf。
memset-0xff 默认值
延迟数组在任何单元格写入前被 memset 为 0xff (255)。不同于 Pufferfish 和 Viperfish(其中每个延迟槽随后都会被覆盖,默认值不会保留),Ghostlite 只写入约 132 个已定价行。其余约 344 条指令在延迟数组中保持 0xff = 255,并且其整个 31 宽网格行(隐式地)保持零初始化值。这些未定价指令不是由该网格定价:其成本来自跨代不变的 CycleTable::GetResource 路径(@0x1c89ce20)或 JfCycleTable 默认的 1 周期。重新实现必须保留 255 作为可区分的 sentinel:调用者读取到 0xff 延迟时知道要回退,而零会与真实的零延迟 op 无法区分。
陷阱 — 网格按
GlcCycleTable构建,而GlcCycleTable从tpu::TpuVersion构造(除GlcCycleTable之外,该 ctor 的唯一调用者是LatencyTableGhostlite::LatencyTableGhostlite(tpu::TpuVersion))。476 行 Ghostlite 集合和 465 行6acc60406集合由实例化哪个CycleTable子类选择,而不是在一个共享对象内部通过运行时分支选择。不要用单个全局指令枚举跨代索引该网格。
GetResourceUsage 读取路径
目的
GetResourceUsage(instr, res) 是吞吐模型和 GetXluPathReservation accessor 用来读取单个网格单元格的唯一 accessor。它在 Pufferfish、Viperfish 和两个 GhPerf 变体之间字节完全相同:同样的两次边界检查和同样用 lea 计算的 24 字节行跨度。因此一个描述覆盖全部四个网格代。
算法
@0x1c8d3700 处反编译出的函数体短且精确:
function GhostlitePerformance::GetResourceUsage(this, instr, res): // @0x1c8d3700
if this.grid_outer_count <= instr: // [this+0x20] ; outer bound = 476
BUG() // ud2 — out-of-range instruction
row_base = this.grid // [this+0x18]
row = row_base + instr*24 // v4 = 3*instr ; row = base + 8*v4 → 24-byte stride
if row.size <= res: // [row+8] ; inner bound = row width (31)
BUG()
return row.data[res] // *(u32*)([row+0] + 4*res) = grid[instr][res]
```text
`GetLatency(instr) @0x1c8d36e0` 是更简单的同级函数:通过 `[this+0x08]`(= 476)对 `latency[instr]` 做边界检查,返回该指令的流水线深度(调度器把 true-dependency edge 提升到的值):
```c
function GhostlitePerformance::GetLatency(this, instr): // @0x1c8d36e0
if this.latency_size <= instr: // [this+0x08]
BUG()
return this.latency[instr] // *(u32*)([this+0x00] + 4*instr)GetResources() @0x1c8d36c0 返回 kResources 遍历顺序:.rodata 中位于 @0xb43cdc4 的字节数组,列出按填充顺序排列的 31 个资源索引:1d 1c 06 03 04 1a 07 08 09 0a 14 10 18 1e 0b 11 00 19 12 13 0c 15 0d 16 0e 17 1b 01 02 05 0f。{0..30} 全部恰好出现一次;Xlu deposit 列 0x0f 在遍历顺序中最后。GetResourceLatency @0x1c8b1e60 迭代该数组来汇总一行(见下文)。
陷阱 — 外层索引是 v6e
GhostlitePerformance::Instruction,不是原始 LLO opcode。每个已填充行的索引都解析到一致的 LLO opcode(所以对已定价行而言,该轴就是 opcode:row0x2d=kParameterAddress,0x77=kScalarLoad,0x16b=kScalarCompare,0x1db= 一个 barnacore-wait 扩展),但映射是按代分类器GetGhostliteInstruction,而 MXU/permute 区段会通过 latch-mode lookup 把单个 opcode fan-out 为多个 ordinal。重新实现若直接按 LLO opcode 索引网格,会误读每个 MXU 行。
opcode 如何到达行 — GetGhostliteInstruction
外层索引由 ghostlite::GetGhostliteInstruction @0x1c8b1740 产生。它首先对 258 项 WORD 重映射表执行无分支二分搜索(一个 (LloOpcode, GhPerf::Instruction) pair 表,通过 GOT 相对寻址到达);命中时返回配对的重映射 word。没有命中重映射表的 opcode 会落入显式 switch,处理无法 1:1 映射的区段:MXU latch op、permute/transpose op 和 compare op,并把每个 fan-out 成多个行:
function GetGhostliteInstruction(value): // @0x1c8b1740 — latency_table_gl.cc
opcode = value.opcode // WORD[value]
// 1. Branchless binary search over the 258-entry WORD remap table (GOT-relative).
hit = bsearch(remap_table, opcode) // 0x1c8b1762..17a1
if hit valid && opcode >= hit.key:
return hit.remapped_instruction // paired WORD
// 2. Fall-through switch on the raw opcode (jt @0xb43b34c, bound opcode-1 ≤ 0xa5).
switch (opcode):
case 1,2,3,4: // kVectorReadIar family — keyed on iar()
CHECK(iar.has_value()) // gl.cc:603/609/615/621
return base ± (iar != 0) // e.g. 471 - (iar==0)
case 139: // kVectorSetPermutePattern (0x8b)
return set_permute_pattern_mode==0 ? 363 : 364
case 141,143,145,147,149: // matpush latch band
mode = latch_mode()
CHECK(target.SupportsGainLatchMode(mode)) // gl.cc:477
return word_B43BDF4[mode] // latch-mode → row WORD
case 142,144,146,148,150: // matprep latch band
return latch_table[latch_mode() - 10] // gl.cc:514
case 155,156,163: // matmul band A — keyed on data format
return matmul_table_A[matmul_data_format() - 1]
case 159,160,164: // matmul band B
return matmul_table_B[matmul_data_format() - 1]
case 166: // transpose — keyed on vxpose_mode()
return {0:368, 1:370, 2:372}[vxpose_mode()]
case 359: // compare — keyed on comparison()
return compare_table[comparison.kind][comparison.dir]
default: LogFatal("Operation not supported") // gl.cc:761
```text
这个 fall-through `switch` 是 MXU/permute/transpose/compare fan-out。单个 matmul opcode(`155/156/163`)会按 `MatmulDataFormat` 映射到最多八个行;单个 latch opcode(`141/143/145/147/149`)会通过 `word_B43BDF4[]` 按 `GainLatchMode` 映射到某个行;permute opcode `139`(`0x8b`)会按 `set_permute_pattern_mode()` 映射到两个行之一。这就是为什么网格有 476 个 *Instruction* 行,但 LLO ISA 中 MXU opcode 远少于这个数量:latch/format modifier 扩展了它们。源文件是 `latency_table_gl.cc`,`CHECK`/`LogFatal` 行号(477、514、603–621、761)是二进制内锚点。
> **怪异点 —** 分类器会对任何未处理的 opcode *trap*(`LogFatal`),而不是返回默认值。所以网格外层索引在*已定价* opcode 集上是全函数,但在 LLO ISA 上是偏函数:既不在 258 项重映射表中、也不在 fall-through switch 中的 opcode 是硬错误,而不是 `0xff` 默认 lookup。`0xff` 默认是对能够分类到某行但该行从未写入的指令的*延迟数组*回退,不是分类器回退。
---
## 资源列
### 目的
网格的内轴是 `GhostlitePerformance::Resource` 枚举:31 个 intra-op EUP/MXU/Xlu 微流水线 reservation 端口。二进制中**没有** `ToString`,所以这些列按功能命名:通过读取哪些 LLO 指令类向每列 deposit 周期(外层索引为 opcode),并用两个具名 accessor `GetXluPathReservation` 和 `GetResourceLatency` 锚定。这些名字在*含义*上足以重新实现(说明每列保留哪个物理端口),但不是字面符号名(MEDIUM)。
> **注意 —** 按代的 `Resource` 枚举(31 列)不同于 23 槽的按 bundle `ResourceVector`([`resource-enum`](resource-enum.md)),层级更低。该网格为 intra-op 微流水线阶段占用定价;`ResourceVector` 是更高层成本模型 deposit 到的按 bundle 功能单元累加器。`kResources @0xb43cdc4` 给出的是网格的列*遍历*顺序,而不是 `ResourceVector` 槽顺序。
### 列区段
31 列组成可识别的区段,对应 EUP/Xlu/MXU-result 微流水线。下表按占用方 LLO 类命名每个区段,而不是转储全部 358 个单元格。列索引是 GL 特有的(GF(`6acc60406`)变体在 result 区段上有 +1 偏移,因为其 EUP-prep 组为 4 列宽,而 GL 为 3 列):
| GL 列 | 区段 | 占用方 LLO 类 | 典型单元格 |
|---|---|---|---|
| r0–r2 | Address / load-store / sync | `kVectorStoreIndexed/Masked`, `kVectorCmemStore`, `kScalarLoad/Store` | 2–3 |
| r3–r5 | EUP transcendental-prep | `kVector{Subtract,Compose,Pack,Tanh,Pow2,Rsqrt,…}` F32/Bf16 | {13,4,3} / {17,8,7} / {25,16,15} |
| r6 | EUP gain-push setup | `kVectorMultiplyU32/U16` | 48 |
| r7–r10 | EUP-result-pop FIFO(4 阶段) | `kVector{…}Bf16AndPop`, `kVectorXorU32/AndU32` | {2,1,3,19} / {6,5,7,39} |
| r11–r14 | Cross-lane / transpose result(4 阶段) | `kScalar{Compare,AddCarry,Multiply}` | {35,34,40,18} |
| **r15** | **Xlu / matrix-result deposit** | `kScalarMultiplyU32/F32`, `kScalarAddS32`, `kScalarSubtractF32` (matres) | **4** |
| r16–r19 | mxres-result 子阶段(4) | matres-result 扩展(`kScalar{Multiply,Add,Subtract}` F32/S32) | {40,44,25,3} / {8,11,35,3} |
| r20–r23 | Pack / extract / U64 阶段(4) | `kScalar{Ceil,CLZ}`, `kVectorCLZ`, extract/U64 ops | {21,25}/{48,50}/{50,54}/{32,36} |
| r24 | Mask-move | `kVectorMaskMove` | 1 |
| r25 | Shift / saturate(仅 v6e 区段) | `kVectorShift{RightLogical,RightArithmetic,LeftLogical}`, `kScalar*Max` | 1 (×14) |
| r26–r27 | BarnaCore scatter-gradients | `kBarnaCore{Global,Local}ScatterGradients` | 5 / 4 |
| r28–r30 | BarnaCore scalar-sync-wait tail | barnacore-wait 区段(opcodes `0x1d0..0x1db`) | 5 / 7 / 3 |
定义性列是 **r15**(`0x0f`):Xlu / matrix-result deposit 端口。它对每个 matrix-result、cmem-result 和 transpose-result op 的单元格都是 `4`:`kScalarMultiplyU32`(`0x16f`)、`kScalarMultiplyF32`(`0x170`)、`kScalarAddS32`(`0x172`)、`kScalarSubtractF32`(`0x174`)。这是卷积成本模型作为其 `R[2]` Xlu 项读取的值。完整逐单元格行没有在此转录;上面的结构允许重新实现者从区段及其占用类重建任何已填充行。
### matrix-result / Xlu deposit 列
`GetXluPathReservation @0x1c8b21c0` 是正好读取列 `0x0f` 的专用 accessor。它特殊处理 permute-pattern opcode,其他情况尾调用 res 15 上的 `GetResourceUsage`:
```c
function LatencyTableGhostlite::GetXluPathReservation(this, value): // @0x1c8b21c0
if value.opcode == 0x8b: // kVectorSetPermutePattern, handled directly
return 3 * (is_transpose(value) ? 1 : 0) + 1
instr = GetGhostliteInstruction(value)
return GhostlitePerformance::GetResourceUsage(this.perf /*[this+0x1d0]*/, instr, 15) // res 0x0f这个反编译体是把 Ghostlite 的 Xlu 列固定在 0x0f 的锚点:res = 15 字面量是 GetResourceUsage 的第三个参数,而 [this+0x1d0](= [this + 58*8])是 LatencyTableGhostlite 内部的 GhostlitePerformance 子对象。Xlu 单元格(= 4)是 conv 成本三元组 R[2] 的 GL 值;matpush 和 matmul 两部分来自单独的 mxu-latency-gl reservation 矩阵。跨代演进为 res 6(PF,conflict-penalty)→ res 0x0e(VF)→ res 0x0f(GL)→ res 0x10(GF),跟随 MXU 几何变化。
GetResourceLatency — 行汇总消费者
GetResourceLatency @0x1c8b1e60 是把网格转换为一对指令 hazard 周期数的消费者。它调用 GetResources() 获得 31 列遍历顺序,并对每一列分别读取两条指令的 GetResourceUsage(instr, res),在两条指令都触及的列上累积 max:
function LatencyTableGhostlite::GetResourceLatency(this, producer, consumer): // @0x1c8b1e60
pi = GetGhostliteInstruction(producer)
ci = GetGhostliteInstruction(consumer)
cols = GetResources() // kResources @0xb43cdc4, 31 entries
result = 0
for res in cols: // traversal order
a = GetResourceUsage(perf, pi, res)
if a == 0: continue
if GetResourceUsage(perf, ci, res) == 0: continue
switch (res):
case 0,1,0x0f,0x18,0x1c,0x1d,0x1e: // "max" columns — take the larger hold
result = max(result, a)
case 0x19: // shift/saturate band — +1 for one opcode range
result = max(result, a + (consumer.opcode-389 < 14))
case 0x1b: // FIFO column — only if push/pop same FIFO
if LloInstructionsPushOrPopSameFifo(producer, consumer):
result = max(result, a)
case 2: LogFatal("Unimplemented") // gl.cc:1040
case 3..0x0a, 0x1a: LogFatal("Did not expect MXU resource") // gl.cc:1066
return result
```text
这个按列 `switch` 证明 31 列不可互换:列 `0..1`、`0x0f`(Xlu)、`0x18`、`0x1c..0x1e` 是简单的“取较大 hold”列;列 `0x1b` 是 FIFO 列,只在两个 op 触及同一 FIFO(`LloInstructionsPushOrPopSameFifo`)时计入;列 `3..0x0a` 和 `0x1a` 是此路径明确拒绝处理的 MXU-reservation 列(`"Did not expected to have MXU resource for "`,`gl.cc:1066`),它们由 `MxuLatencyTable` 定价,而不是这里。列 `0x19` 是 v6e shift/saturate 区段,会对特定 consumer opcode 范围(`opcode - 389 < 14`)额外增加一个周期。
> **注意 —** MXU 列(`3..0x0a`、`0x1a`)上的 `LogFatal` 是有意断言,不是死代码:如果 producer/consumer 对都 deposit 到 MXU 列,它们不应到达 `GetResourceLatency`,因为 MXU hazard 由独立的 `MxuOpHoldIssues` 递推在 `MxuLatencyTable` 上计算。网格列 `3..0x0a` 携带单元格(EUP-prep 区段),但由其他路径读取,绝不会由这个 pairwise hazard sum 读取。
---
## 476-vs-465 指令集差异
Ghostlite(v6e)有 476 个 `Instruction` 行;`6acc60406`(v7)有 465 个,即 v6e 多出 `+11`。额外 v6e opcode 在网格中的两个位置出现:(a)仅 GL 填充的 **r25** shift/saturate 区段(14 个单元格,shift-right/left 和 scalar/vector-max overflow-saturate op `0x19a..0x1bb`,GF 要么融合它们,要么路由到别处;GF 的 r25 等价列只有一个单元格);以及(b)扩展的 BarnaCore-wait opcode `0x1d0..0x1db`,它们位于 461 项 LLO opcode 名称范围之外(最后一个具名 LLO opcode 是 `0x1cc = kBarnaCoreVectorStore`)。因此,`+11` 个 v6e 额外指令是额外的 shift/saturate 加 barnacore-wait 变体;`6acc60406` 去掉它们,得到更小的 465 行集合。`0x1d0..0x1db` 行的名称是从其值模式匹配 GF barnacore-wait 区段推断出来的(MEDIUM);它们没有逐个解析。
---
## 示例 — conv R[2] Xlu 单元格
Ghostlite 卷积成本计算会读取每个 matrix-result op 的 Xlu 吞吐。`GetXluPathReservation @0x1c8b21c0` 通过 `GetGhostliteInstruction` 对 op 分类,然后读取 `GetResourceUsage(perf, instr, 15)`。对每个 matres-result op,网格都持有 `grid[instr][0x0f] = 4`:
```text
opcode kScalarMultiplyF32 (0x170) → GhPerf row 0x170, lat 123 → grid[..][0x0f] = 4
opcode kScalarAddS32 (0x172) → GhPerf row 0x172, lat 97 → grid[..][0x0f] = 4
opcode kScalarSubtractF32 (0x174) → GhPerf row 0x174, lat 109 → grid[..][0x0f] = 4因此 GL conv R[2] Xlu 项为 4 · ChunksPerTile · rem。R[0] matpush 和 R[1] matmul 两部分来自 mxu-latency-gl reservation 矩阵(matpush {2 bf16 / 4 fp8},matmul {4 bf16 / 8 fp8})。这里每个 op 的基础延迟(123/97/109,以及 EUP-prep 区段的 192/182)是 v6e silicon 的流水线深度,低于 6acc60406 的 212/204,这是可见的 silicon 代际差异。Xlu 单元格 4 本身与 dtype 无关,并与 6acc60406 值匹配;只有周围延迟不同。
函数映射
| 函数 | 地址 | 角色 |
|---|---|---|
ghostlite::GhostlitePerformance::GhostlitePerformanceC1Ev | 0x1c8cbc80 | GL 网格 ctor — latency new 0x770,grid new 0x2ca0;834 个存储(476 lat + 358 grid) |
ghostlite::GhostlitePerformance::GetResourceUsage | 0x1c8d3700 | 网格读取 — 外层边界 [this+0x20],24 字节 stride,内层边界 [row+8] |
ghostlite::GhostlitePerformance::GetLatency | 0x1c8d36e0 | 延迟读取 — latency[instr],边界 [this+0x08] |
ghostlite::GhostlitePerformance::GetResources | 0x1c8d36c0 | 返回 kResources @0xb43cdc4(31 字节遍历顺序) |
ghostlite::GetGhostliteInstruction | 0x1c8b1740 | LLO opcode → Instruction 行;WORD bsearch + MXU latch fan-out(jt @0xb43b34c) |
ghostlite::LatencyTableGhostlite::GetXluPathReservation | 0x1c8b21c0 | 读取 Xlu 列 res 0x0f;conv R[2] accessor |
ghostlite::LatencyTableGhostlite::GetResourceLatency | 0x1c8b1e60 | 遍历 31 列的 pairwise hazard sum;按列 switch |
GlcCycleTable::GlcCycleTable | 0x1c89e7e0 | 所有者 CycleTable — 网格位于 this+0x10,MxuLatencyTable 位于 this+0x18 |
CycleTable::GetResource | 0x1c89ce20 | 0xff 默认未定价行的回退成本路径 |
相关组件
| 名称 | 关系 |
|---|---|
performance-overview | 家族框架:扁平与网格 Performance、共享读取路径、资源演进 |
performance-gf-ghperf | 6acc60406 (v7) GhPerf 孪生 — 465×31,Xlu res 0x10,基础延迟 212/204 |
mxu-latency-gl | 与该网格共存的单独 Ghostlite MxuLatencyTable(matmul/matpush reservation) |
resource-enum | 23 槽的按 bundle ResourceVector,不同于 31 宽的 GhostlitePerformance::Resource |
slot-mxu | 资源列保留的物理 MXU 子单元 |
交叉引用
- 性能家族概览 — 网格家族对象布局、共享的
GetResourceUsage/GetLatency读取路径,以及 7→7→20→28→31→31 资源演进 - 性能:GF (GhPerf 465×31) —
6acc60406(v7) GhPerf 孪生;Xlu deposit res0x10、基础延迟 212/204,以及 476-vs-465 指令集差异 - MXU 延迟:GL (Ghostlite) — 单独的 v6e
MxuLatencyTablereservation 矩阵;该网格R[2]对应的 convR[0]/R[1]matpush/matmul 两部分 - 资源枚举(23 槽) — 按 bundle 的
ResourceVector,不同于按代Performance::Resource微流水线列 - MXU 槽 — LLO MXU 指令槽,其 latch-mode/format modifier 驱动
GetGhostliteInstructionfan-out