Skip to content

MXU 延迟:PF

地址适用于来自 libtpu-0.0.40-cp314 wheel 的 libtpu.so。其他版本会有所不同。

摘要

本页记录 Pufferfish (v4) 如何为 MXU 流水线占用定价,其中最主要的结论是结构性的:Pufferfish 没有单独的 MxuLatencyTable Viperfish、Ghostlite 和 6acc60406 会分别在其 LatencyTable+0x1d8 槽上堆分配一个 reservation-matrix 对象,即每个 MXU op family 一个 flat_hash_map<Modifier, array<int,N>>,并由从 MatmulDataFormat 构造的 modifier key 索引;这个对象在 Pufferfish 成本模型中不存在。二进制中没有 xla::pufferfish::MxuLatencyTable 类;唯一的 MxuLatencyTable 类型是 xla::viperfish::xla::ghostlite::,以及 anonymous-namespace 的 6acc60406 变体(lookup @0x1c8bdb20, gf.cc)。因此 Pufferfish 的行为类似 Jellyfish/Dragonfish:它把 MXU 占用折入其他成本对象,而不是放进专用的 reservation table。

具体来说,Pufferfish 在两个位置为 MXU 占用定价。第一,matmul throughput 作为 PufferfishPerformance grid 中的一列存在:res 9,一个 96-cell 列,在整个 matmul band(Instruction 0x7a..0xd9)上携带 value-set {8, 16},由 byte-identical grid GetResourceUsage @0x1c8c3880 读取。第二,transpose / cross-lane (Xlu) reservation 由单独的 XluConflictPenaltyTable 定价,这是一张嵌入 LatencyTablePufferfish +0x18 的 3-axis integer table,通过 XposeXLUReservationLatency @0x1c8a13e0 读取。这正是 performance-pf 页面从 grid 侧描述的分拆;本页从 MXU-occupancy 侧描述它,并说明任务简报所要求的 per-(MatmulMode × MatmulDataFormat) reservation-matrix body 为什么在 v4 中不存在。

参照系是同族的其他模型。在 Viperfish 上,matpush 会被压缩为一个 MatpushModifier key,在 flat_hash_map 中查找,并产生一个密集的 per-MxuResource hold cycles array<int,19>({2,1,1} bf16 → {8,7,6} int8-x8)。在 Pufferfish 上,同样的物理占用通过 grid 的 matmul-throughput cell(8 narrow / 16 wide)加 conflict-penalty matrix 表达;reservation map 层完全缺失。v4 成本模型的重新实现不得构建 MxuLatencyTable;它必须通过 PufferfishPerformance(res 9)和 XluConflictPenaltyTable 为 MXU op 定价。

重新实现的契约是:

  • Pufferfish 携带没有 MxuLatencyTable 对象(没有 this+0x00 matpush map,没有 this+0x20 matmul map)——简报中的 reservation-matrix 布局描述的是 Viperfish,不是 PF。
  • PF 实际为 MXU throughput 定价的位置:matmul 使用 PufferfishPerformance res 9({8,16}),latch 使用 matprep band(res 10/11),matrix-result deposit 使用 res 6(kVectorMatres)。
  • XluConflictPenaltyTable(3-axis [XluInstrType][6][3])以及 XposeXLUReservationLatency,它们取代 grid column 或 reservation map 来为 transpose/Xlu reservation 定价。
  • MxuResource 列数问题:PF 根本没有 MxuResource enum;它的 MXU 列是 20-wide grid 内的 PufferfishPerformance::Resource ordinal。
MxuLatencyTable —— 二进制中不存在 xla::pufferfish::MxuLatencyTable 符号
MXU throughputPufferfishPerformance grid res 9(96 cells,value-set {8,16}@0x1c8c3880
Matprep throughputgrid res 10(value 7),res 11/12(transpose-binary / matprep result)
Matrix-result depositgrid res 6 = kVectorMatres(0x77),value 8
Xlu / transpose 定价XluConflictPenaltyTable(3-axis)via XposeXLUReservationLatency @0x1c8a13e0
Penalty tableLatencyTablePufferfish +0x18;ctor @0x1c8a1960 中 10 次 SetXluConflictPenaltyBetween 安装
MxuResource countn/a —— PF 使用 PufferfishPerformance::Resource(20 列),不是 per-gen MxuResource enum
GenerationPufferfish,TpuVersion 2 / v4(LatencyTablePufferfish,object 0x1e0 B)

Pufferfish 没有 MxuLatencyTable

Pufferfish 拥有 MxuLatencyTableLatencyTablePufferfish(ctor @0x1c8a1960)没有分配它:它在 [this+0x1d0] 存储 GetSharedPufferfishPerformance,在 [this+0x1d8] 存储 GetSharedPufferfishBarnaCorePerformance(两个 Performance grid,而不是 reservation map),并在 [this+0x18] 构建一个 inline XluConflictPenaltyTable。符号表中任何位置都不存在 xla::pufferfish::MxuLatencyTable 类、ctor 或 GetResourceUsage

陷阱 — reservation-matrix 模型(this+0x00 处的 matpush map、this+0x20 处的 matmul map、array<int,19> body、{2,1,1}/{4,3,2}/{8,7,6} value-set)是 Viperfish 模型(mxu-latency-vf);它从 v5p 才首次出现,而不是 v4。Viperfish、Ghostlite 和 6acc60406 携带这张表;Jellyfish、Dragonfish 以及 Pufferfish 都没有。不要假设 PF 上的 LatencyTable + 0x1d8 槽是 reservation map —— 它是第二个 Performance grid。

反编译显示的内容

Pufferfish LatencyTable ctor 会把自身 0x1e0-byte body 清零,设置 vtable,然后连接两个 Performance singleton 和一张 conflict table —— 没有 map 构建,没有 SetReservations,也没有 modifier key 的 flat_hash_map

c
function LatencyTablePufferfish(this, version):              // @0x1c8a1960
    LatencyTable_base(this, version)                          // zero 0x1e0 body, set vptr off_21C20330
    [this+0x1d0] = GetSharedPufferfishPerformance()           // TensorCore grid (pf_shared @0x22579a10)
    [this+0x1d8] = GetSharedPufferfishBarnaCorePerformance()  // BarnaCore grid (pf_bc_shared)
    // inline std::vector<int>-shaped scratch at +0x20/+0x74/+0xC8/+0x11C/+0x168/+0x1BC (size/cap 1 or 9)
    InitializeConflictLatency(this)
    SetXluConflictPenaltyBetween(this, 0, 2, 0, 56)           // 10 penalty installs into the +0x18 table
    SetXluConflictPenaltyBetween(this, 5, 2, 0, 46)
    SetXluConflictPenaltyBetween(this, 0, 5, 0, 17)
    SetXluConflictPenaltyBetween(this, 2, 5, 0, 96)
    SetXluConflictPenaltyBetween(this, 2, 0, 0, 86)
    SetXluConflictPenaltyBetween(this, 0, 2, 1, 56)           // second hi-plane duplicates the first five
    SetXluConflictPenaltyBetween(this, 5, 2, 1, 46)
    SetXluConflictPenaltyBetween(this, 0, 5, 1, 17)
    SetXluConflictPenaltyBetween(this, 2, 5, 1, 96)
    SetXluConflictPenaltyBetween(this, 2, 0, 1, 86)
```text

对比 Viperfish ctor(`@0x1c8a52c0`,约 27 KB),它会 `new` 一个 `MxuLatencyTable`,并通过 `SetReservations<MatpushModifier>`/`<MatmulModifier>`/`<MatresModifier>`/`<VlxmrModifier>` 填充四个 `flat_hash_map`。Pufferfish 的 ctor 小了两个数量级,因为它没有这样的 map 要构建。MXU 占用已经烘焙进 ctor 只负责指向的 `PufferfishPerformance` grid 中。

> **说明 —** PF ctor 在 `+0x20`、`+0x74`、`+0xC8`、`+0x11C`、`+0x168`、`+0x1BC` 清零填充的 inline `std::vector<int>`-shaped field(每个设置为 `{ptr=0, size=cap=1}` 或 `{..=9}`)是 base `LatencyTable` 的 per-XLU scratch vector,不是 MXU reservation map。它们持有 `{1,1,1,9,1,1}` size/cap seed,即 `xlu_count=2` Pufferfish XLU-edge scratch,并且与 v5p+ `MxuLatencyTable` 的 matmul/matpush reservation family 无关。

---

## Pufferfish 在何处为 MXU 占用定价

### Matmul 和 matprep throughput —— grid

Viperfish 存入其 `MatmulModifier` reservation array 的 matmul throughput,Pufferfish 则存为 grid cell。`PufferfishPerformance::GetResourceUsage(instr, res)` `@0x1c8c3880` 读取 `grid[instr][res]`;matmul band 占用 res 9

| MXU 角色 | Grid column | Cells | Value(s) | 含义 |
|---|---|---:|---|---|
| matmul throughput | res 9 | 96 | `{8, 16}` | per-issue hold;8 = narrow format,16 = wide |
| matprep throughput | res 10 | 20 | `7` | per-issue matprep latch hold |
| matprep / transpose result A | res 11 | 54 | `{1, 8, 16}` | matprep + transpose-binary + permute/rotate result |
| transpose / permute result B | res 12 | 34 | `{1, 8, 16}` | 第二个 transpose/permute result stage |
| matrix-result (Xlu) deposit | res 6 | 1 | `8` | `kVectorMatres`(0x77)—— conv `R[2]` analog |

res 9 上单一的 value-set `{8, 16}` 是 VF `{2,1,1}/{4,3,2}/{8,7,6}` reservation triplet 的 PF 对应物:narrow(bf16-class)matmul 持有 throughput port 8 cycles,wide(int8/x8-class)matmul 持有 16。不存在单独的 matpush/matmul/matres/vlxmr map,因为 grid 的外层 `Instruction` axis 已经按数据格式把 matmul/matprep opcode 展开到整个 band(通过 `GetPufferfishInstruction` 中的 latch-mode WORD table)。matmul base **latency**(band 开头两个 byte-confirmed format depth 83101,`latency[0x7A]=83`;两者 narrow/wide 归属是推断的,而非逐字节枚举 —— 见 [`performance-pf`](performance-pf.md))是总 op depth;res-9 cell(8 / 16)是约束 back-to-back issue 的 throughput hold。

> **特性 —** matmul-throughput 表示方式会逐代变宽,而 Pufferfish 是最窄的:PF 上是单一 res-9 列(96 cells),VF 上是 res-3 列加 4-stage matprep group(res 4..7),GL/GF 上是更宽的 EUP-AndPop FIFO。同样的物理占用在 PF 上是一列,在 VF 上是七列。把 VF multi-stage matprep group 移植到 PF 的重新实现,会建模 PF 的 20-column grid 并不存在的 resource port。

### Transpose / Xlu reservation —— conflict-penalty table

VF/GL/GF 从 Xlu grid column(`GetXluPathReservation`)读取的 transpose 和 cross-lane (Xlu) reservation,Pufferfish 则从专用 `XluConflictPenaltyTable` 定价。`XposeXLUReservationLatency` `@0x1c8a13e0`:

```c
function XposeXLUReservationLatency(this, mode, earlier, later, a, b):  // @0x1c8a13e0
    CHECK(IsTranspose(earlier))                          // latency_table_pf.cc:62
    v = (b - a) + XluConflictPenaltyBetween(&this.penalty /* +0x18 */, earlier, later_lo, later_hi)
    if v < -5: v = -6
    return v + 7

XluConflictPenaltyBetween @0x1c8a0180 是 3-axis lookup —— penalty[XluInstrType][lo<6][hi<3],stride 72*type + 12*lo + 4*hi + 8,返回已存储的 penalty + 1IsTranspose(type)(type - 2) < 3,因此 XluInstrType ordinal {2,3,4} 是 transpose op;CHECK 强制一对 op 中的 earlier op 必须是 transpose。ctor 安装的 10 个 penalty pair 为 transpose-result producer 与后续 Xlu consumer 之间的 conflict cycles 定价((0→2)=56(2→5)=96(2→0)=86(5→2)=46(0→5)=17,每个在两个 hi plane 上重复)。

AccessorAddress角色
XposeXLUReservationLatency0x1c8a13e0transpose/Xlu reservation = (b−a) + penalty + 7,带 clamp
LatencyBetweenXposeInstrAndResult0x1c8a1520通过 penalty table 计算 transpose-instr → result edge
XluConflictPenaltyBetween0x1c8a01803-axis read [type][6][3],返回 penalty+1
XluConflictPenaltyTable::IsTranspose0x1c8a04e0(type − 2) < 3 → types {2,3,4}
SetXluConflictPenaltyBetween (PF)0x1c8a17e0安装 penalty;CHECK(!IsPacked(earlier) && !IsPacked(later))

陷阱 — conflict-penalty 模型是有方向且成对的,不是 per-op reservation。VF/GL/GF 的 GetXluPathReservation 为一个 op 返回一个数字(它持有 Xlu deposit port 的 cycle 数);PF 的 XluConflictPenaltyBetween 返回 earlier transpose 与 later Xlu op 之间的 penalty。把 PF penalty matrix 映射为 single-op Xlu reservation 的重新实现,会彻底丢失 conflict structure —— PF 把 Xlu hazard 建模为 producer→consumer edge,后续代则建模为 port hold。


MxuResource 问题

简报类比 Viperfish 的 array<int,19> 和 Ghostlite 的 array<int,11>,询问 PF 的 MxuResource 列数。Pufferfish 没有 MxuResource enum。 MxuResource enum 是 MxuLatencyTable 的 value-array index space,而 PF 没有 MxuLatencyTable。MXU sub-unit 反而是 PufferfishPerformance::Resource enum 中的列,即 20-wide grid axis(performance-pf),其中 res 9 是 matmul throughput,res 10 是 matprep,res 6 是 matrix-result deposit。PF 没有 kNumMxuResources CHECK 常量(约束 VF/GL lookup 的 0x13=19 / 0xB=11 bound),因为不存在 per-MxuResource read 需要约束。

因此 Pufferfish 的 resource-count 答案是:MXU 占用存在于 20-column PufferfishPerformance::Resource grid 中,而不是单独的 MxuResource-indexed reservation array 中。MxuResource 模型从 Viperfish 才开始。

GenMxuLatencyTable?MxuResource countMXU throughput home
Jellyfish / Dragonfishnon/ainline 15-field latency model
Pufferfishnon/aPufferfishPerformance grid res 9 + XluConflictPenaltyTable
Viperfishyes19(array<int,19>MxuLatencyTable @this+0x1d8
Ghostliteyes11(array<int,11>MxuLatencyTable @this+0x1d8
6acc60406 (TPU7x)yes11(array<int,11>MxuLatencyTable @this+0x1d8(anon-ns,lookup @0x1c8bdb20

函数映射

FunctionAddress角色
LatencyTablePufferfish::LatencyTablePufferfish0x1c8a1960ctor —— 连接两个 Performance grid + conflict table;没有 MxuLatencyTable
PufferfishPerformance::GetResourceUsage0x1c8c3880MXU throughput read —— grid[instr][res 9]
PufferfishPerformance::PufferfishPerformance0x1c8be080grid ctor —— res 9 matmul column(96 cells,{8,16}
XposeXLUReservationLatency0x1c8a13e0替代 reservation map 的 transpose/Xlu reservation
XluConflictPenaltyBetween0x1c8a01803-axis penalty table read
SetXluConflictPenaltyBetween (PF)0x1c8a17e010 个 ctor penalty install
ResourceUsageFromInstruction (variant 0/1)0x1c8a3180 / 0x1c8a31a0TC/BarnaCore grid dispatch —— MxuLatencyTable family select 的 analog
GetSharedPufferfishPerformance singleton0x22579a10PF 用来为 MXU op 定价的 grid
viperfish::MxuLatencyTable::MxuLatencyTable0x1c8a52c0PF 没有的 v5p reservation-table ctor —— 用于对照

相关组件

NameRelationship
mxu-latency-overviewper-gen MxuLatencyTable 模型 —— PF 是缺少它的 v4 例外
performance-pf为 PF MXU throughput(res 9)定价的 PufferfishPerformance grid + conflict table
mxu-latency-vfViperfish array<int,19> reservation matrix —— PF 之前尚未出现的模型
matmul-mode-modifiersMatmulDataFormat code;在 PF 上它们选择 grid band ordinal,而不是 modifier key
resource-enum23-slot per-bundle ResourceVector,不同于 PF 20-column grid

交叉引用

  • MXU 延迟概览 —— per-gen MxuLatencyTable reservation model;Pufferfish 是像 JF/DF 一样缺少它的 v4 generation
  • Performance:PF —— PufferfishPerformance grid(res 9 matmul throughput,res 6 matrix-result)以及共同承载 PF MXU occupancy 的 XluConflictPenaltyTable
  • MXU 延迟:VF —— Viperfish array<int,19> reservation matrix,以及 v5p 首次引入的 {2,1,1}/{4,3,2}/{8,7,6} value-set
  • MXU 延迟:GL (Ghostlite) —— Ghostlite array<int,11> reservation matrix
  • MXU 延迟:GF (6acc60406) —— 6acc60406 array<int,11> reservation matrix(lookup @0x1c8bdb20
  • MatmulMode 与 Modifiers —— MatmulDataFormat code;在后续 generation 上它们构建 reservation-map key,在 PF 上它们选择 grid band ordinal
  • MXU Slot —— PF 通过 grid 定价的 LLO MXU instruction slot
  • Matprep / IAR / Latch —— 后续代 table 所基于 matpush family key 的 latch/matprep op