jxc DMA / HbmMux / brn_perf 频带
本页所有地址适用于
libtpu.sov0.0.40(libtpu-0.0.40-cp314,build-id89edbbe81c5b328a958fe628a9f2207d)。.text/.rodata中的 VMA 等于文件偏移;.data.rel.ro的 VMA 相对文件偏移为 -0x200000。其他版本会不同。
摘要
本页解码三个最早一代(Jellyfish,编解码器族 jxc)用于剖析数据移动的设备跟踪频带:Dma 频带(按引擎记录、由 flow id 连接的 DMA 传输跨度)、HbmMux 频带(HBM 多路复用器方向 FSM),以及 brn_perf1 / brn_perf2 频带(BarnaCore 性能计数器)。这三者都由针对 asic_sw::driver::deepsea::jxc::PerformanceTraceEntry 的 XProf subscriber 模板特化消费;它是 proto2 自描述跟踪记录,早于 deepsea(pxc)和 SparseCore 世代的位打包 packet 编解码器。把 PerformanceTraceEntry 分类到这些频带的 proto2 路径另见 jxc 旧式载荷;本页负责 DMA XStat 发射、HbmMux 状态机和 BarnaCore perf 载荷。
三个子系统共享同一种形状。Dma subscriber(DmaSubscriber<jxc>::ProcessTraceEntry @ 0xf1dfee0)把一个 *_COMMAND 开始 trace entry 与其匹配的 *_DATA_END 完成项配对,使用以合成 dma_id 为键的 FlatHashMap,然后在按引擎划分的 XLine 上绘制 XEvent,并携带 XProf flow stat,使 profiler 渲染从开始到结束的箭头。HbmMux subscriber(HbmMuxSubscriber<jxc>::ProcessTraceEntry @ 0xf1def00)是一个四符号开/关 FSM,用于计时 HBM 读/写多路复用器指向 BFIFO 与 Node Fabric 的时长。brn_perf 频带是反射驱动的 perf 记录,覆盖三个固定 BarnaCore reduce 算子(brn_perf1)和十六个 DMA channel controller(brn_perf2)。
本页是 BarnaCore 作为实时引擎的运行时可观测性指纹:HBM mux、三个融合 reduce 算子和十六个流 channel controller 的独立 profiler 频带,正是 SparseCore 世代所替换的微架构(TpuComponent enum 保留这些 ordinal;没有 v3+ trace 会填充它们)。对重新实现而言,契约是:
- Dma flow 协议:COMMAND/DATA_END gate mask、
(nf.id - 3)引擎 switch、按引擎的 XLine 与 Read/Write/Receive 显示名,以及flowXStat 值公式。 GetDmaId复合键:用于把 begin 与 end 配对的精确 OR/shift 位布局,以及哪些 proto2 字段馈入每个位窗口。- HbmMux FSM:四个
fsm符号、open/close 配对,以及由两份 metadata 选择的事件名。 - nf_descriptor 3 通道 sync-flag 载荷,以及 brn_perf1/brn_perf2 字段表及其按 id 分配的 XLine。
| Dma subscriber | xprof::tpu::DmaSubscriber<jxc::PerformanceTraceEntry>::ProcessTraceEntry @ 0xf1dfee0 |
| HbmMux subscriber | xprof::tpu::HbmMuxSubscriber<jxc::PerformanceTraceEntry>::ProcessTraceEntry @ 0xf1def00 |
| DMA-id composer | TraceEntryWrapper<jxc>::GetDmaId @ 0xf698180 |
| COMMAND / DATA_END gate | MemoryCommand @ 0xf698560 (mask 0x56B6D8) / MemoryDataEnd @ 0xf6985a0 (mask 0x894920) |
| Flow stat | StatType 56 = "flow";值 ((dma_id & 0x00FFFFFFFFFFFFFF) << 2) | 3 |
| HbmMux XLine | TpuComponent 56 = "HBM Mux"(TpuComponentName @ 0x1c8ebb60) |
| Record discriminator | submsg-ptr +0x30 处的 EntryDataCase;submsg +0x30 处的 nf band sub-id(别名) |
Dma 频带 — 按引擎的传输跨度
目的
Dma 频带把 DMA trace entry 流转换为按引擎划分的时间线,每次传输显示为一个持续时间 XEvent,并通过 XProf flow 箭头把 begin/end 对可视化连接起来。跨度自身没有 byte-count;引擎和方向由跨度落在哪个 XLine 以及事件的 display name("Read" / "Write" / "Receive")编码;begin↔end 配对由 flow stat 承载。
入口点
DmaSubscriber<jxc>::ProcessTraceEntry (0xf1dfee0)
├─ CoreId(entry) (chip/core filter: a1+8 vs a1+12)
├─ MemoryCommand() | MemoryDataEnd() (0xf698560 / 0xf6985a0 — gate)
├─ switch (nf.id - 3) (jt @ 0xab531a4, arms 0..0x14)
│ └─ sets XLine r15d + display-name blob + kind r14
├─ GetDmaId() (0xf698180 — FlatHashMap key)
├─ find_or_prepare_insert_large (0xf1e05e0 — pending-begin map)
├─ GetOrCreateLine(XLine) (0xf1df120)
├─ AddEvent (0xf1df1e0)
└─ AddStatValue (flow) (XStatsBuilder; metadata at a1+0x18)
```text
### 算法
```c
function DmaSubscriber_ProcessTraceEntry(self, entry): // 0xf1dfee0
if CoreId(entry) != {self+8, self+12}: return // chip/core filter
if !MemoryCommand(entry) && !MemoryDataEnd(entry): return // not a DMA edge
if EntryDataCase(entry) != 6: return // must be the nf band
arm = nf.id - 3 // nf.id at nf-submsg+0x30
switch arm: // jt @ 0xab531a4
case 0: xline=57; name="Read"; kind=4 // HBM_READ_COMMAND
case 1,2: xline=57; name="Write"; kind=5 // HBM_WRITE cmd/data-end
case 3,6: xline=19; name="Read"; kind=4 // VMEM read cmds
case 4,5,7,8: xline=19; name="Write"; kind=5 // VMEM write cmd/data-end
case 9: xline=20; name="Read"; kind=4 // SMEM_READ_COMMAND
case 10,11: xline=20; name="Write"; kind=5 // SMEM write cmd/data-end
case 12,13: xline=18; name="Write"; kind=5 // IMEM write cmd/data-end
case 17: xline=51; name="Receive"; kind=7 // HIB_WRITE_RECEIVE
case 19,20: xline=52; name="Write"; kind=5 // HIB write cmd/data-end
default: return // BMEM/ICI_SEND_END dropped
dma_id = GetDmaId(entry) // 0xf698180
if presence_byte != 1: return // no id -> drop
slot = map[dma_id] // FlatHashMap<dma_id, vector<entry>>
if MemoryCommand(entry) && First(entry): // 0xf698620
slot = [entry] // open a pending begin
else:
slot.push_back(entry)
if kind != 5: return // only the DATA_END family closes
is_not_write = (load32(name) ^ 0x74697257) // "Writ" LE
| (load8(name+4) ^ 0x65) != 0 // 'e' -> "Write" compare @ 0xf1e0152
// close only on a Write-labelled DATA_END with a pending begin
if MemoryDataEnd(entry) ... :
if Last(entry) && slot.nonempty(): // 0xf698660
begin = slot[0]
start = begin.gtc // *(begin+16)+24
dur = entry.gtc - start
line = GetOrCreateLine(self.builder, xline) // 0xf1df120
ev = AddEvent(line, start, dur, name) // 0xf1df1e0
flow = ((dma_id & 0x00FFFFFFFFFFFFFF) << 2) | 3 // lea 0x3(,rax,4)
AddStatValue(ev, self.flow_metadata /*+0x18*/, flow)
map.erase(dma_id) // 0xf1e05a0陷阱 — close 路径由一次 针对
"Write"的字符串比较 控制,而不是仅由 trace-point kind 控制。在0xf1e0152,subscriber 将显示名的前四个字节与0x74697257("Writ")异或,并将第五个字节与0x65('e')异或。若重新实现仅根据*_DATA_ENDtrace-point id 关闭跨度,会错误处理 read 路径(它们从不携带 "Write" 名称)以及"Receive"HIB 路径(kind 7)。判别器是按 arm 设置的 label。
按引擎映射
十七个 DMA edge 解析为六个 XLine。XLine 是一个 TpuComponent ordinal,由 TpuComponentName @ 0x1c8ebb60 解码;显示名 blob 位于 off_21643E10/E20/E30(R_X86_64_RELATIVE addend → "Receive"/"Read"/"Write")。
arm (nf.id) | 事件 | XLine | 显示名 | kind |
|---|---|---|---|---|
| 0 (3) | HBM_READ_COMMAND | 57 "HBM" | Read | 4 |
| 1 (4) / 2 (5) | HBM_WRITE cmd / data-end | 57 "HBM" | Write | 5 |
| 3 (6) / 4 (7) / 5 (8) | VMEM↔HBM read/write cmd / data-end | 19 "Tensor Core VMEM" | Read/Write | 4/5 |
| 6 (9) / 7 (10) / 8 (11) | VMEM↔ICI read/write cmd / data-end | 19 "Tensor Core VMEM" | Read/Write | 4/5 |
| 9 (12) / 10 (13) / 11 (14) | SMEM read/write cmd / data-end | 20 "Tensor Core SMEM" | Read/Write | 4/5 |
| 12 (15) / 13 (16) | IMEM write cmd / data-end | 18 "Tensor Core IMEM" | Write | 5 |
| 17 (20) | HIB_WRITE_RECEIVE | 51 "From Host Interface" | Receive | 7 |
| 19 (22) / 20 (23) | HIB write cmd / data-end | 52 "To Host Interface" | Write | 5 |
注意 —
nf.id17/18/19(BMEM)和 27(ICI_SEND_END)的 switch arm 会路由到 drop 出口;BMEM 有GetDmaIdcomposer,但 Dma subscriber 从不注册它。Reads(First)打开一个 pending begin;匹配的 write/receiveDATA_END(Last)关闭它。一次传输的 byte count 不在 flow stat 中;它可通过GetDmaSize@0xf6982a0单独取得(length << 10,1 KiB 单位;EntryDataCase3 读取source_offset+0x48,case 19 读取+0x2c)。
Flow Stat
Dma subscriber 发射的唯一 XStat 是 StatType 56,名称 "flow"(通过 GetStatTypeMap @ 0x1cf8c660 解析;subscriber 的 StatMetadata 缓存在对象偏移 +0x18,并经由 self+0x18 处的 builder 以 *(self+0x18) 传给 AddStatValue)。该值以内联方式构造:
flow_value = ((dma_id & 0x00FFFFFFFFFFFFFF) << 2) | 3 // lea 0x3(,rax,4) over 56-bit mask
```text
`dma_id` 的低 56 位是 flow identity;低两位 tag `3` 标记一个 both-ends flow link。因为一次传输的 begin 和 end XEvent 共享同一个 `dma_id`,它们共享同一个 flow id,XProf 因而绘制箭头。`dma_id` 是 `FlatHashMap` 键,因此配对和 flow 渲染使用同一个复合键。
---
## GetDmaId — Begin/End 配对键
### 目的
`GetDmaId` @ `0xf698180` 派生合成的 27 位键,用于把一个 `*_COMMAND` 与其 `*_DATA_END` 配对。它是 deepsea 位打包 composer `TraceEntryWrapper<pxc>::GetDmaId(int)` @ `0xf699ca0` 的 `jxc` proto2 字段类比:deepsea 路径从 16 字节 packet 中切片位窗口,而 `jxc` 路径折叠 proto2 message 字段。
> **注意 —** `GetDmaId` 的 switch 根据 **`EntryDataCase`** 判别器(`*(submsg_ptr + 0x30)`,proto2 oneof tag)分发,而不是根据 `(nf.id - 3)`。`(nf.id - 3)` switch 是另一个独立键,即 *Dma subscriber 的* 引擎选择器(`0xf1dfee0`)。在 `GetDmaId` 中,`case 3` 读取 `nf_descriptor` 布局,`case 4/5/6/8` 读取 cmd/data-end 布局,`case 0x12/0x13` 读取另外两个 oneof arm。Cases `7,9..0x11` 直接跳到 composite-merge label(`0xf69824e`),完全不加载字段;函数入口处会清零 `eax`/`edx`(`xor eax,eax; xor edx,edx`),因此 merge(`movzbl al; or ecx`)折叠 `0 | 0`,这些 arm 返回 `0`,不是 `id & 0xff`。应把两个 switch 视为不同的分发键。
### 算法
```c
function GetDmaId(self): // 0xf698180
msg = *(self + 16)
a = 0; node = 0 // xor eax,eax; xor edx,edx at entry
switch EntryDataCase(msg): // *(msg + 0x30)
case 3: // nf_descriptor
a = field[8] // trace_id (+0x20)
node = field[9] // node_id (+0x24)
rsrc = field[32] // descriptor_source (+0x80)
chip = field[10] // chip_id (+0x28)
goto TAIL_A
case 4: case 6: // command arms
a = field[7]; node = field[8]; rsrc = field[13]
chip = field[9]; goto TAIL_A
case 5: // data-end arm
a = field[7]; node = field[8]; rsrc = field[14]
chip = field[9]; goto TAIL_A
case 8: // vmem-hbm data-end arm
a = field[7]; chip = field[8]; rsrc = field[21]; node = field[9]
goto TAIL_A
case 0x12: a=field[8]; node=field[6]; rsrc=field[17]; chip=*(msg+32); goto TAIL_A
case 0x13: a=field[7]; node=field[6]; rsrc=field[15]; chip=*(msg+32); goto TAIL_A
case 7,9,10,11,12,13,14,15,16,17: // simple
return 0 // a/edx never reassigned; eax=0 at entry
default: return 0
TAIL_A:
mid = (a & 0x1F00) | ((rsrc & 3) << 13) | ((node << 15) & 0xFFFF)
full = mid | ((chip << 16) & 0x7FF0000)
return full | (a & 0xff)位布局
一个 TAIL_A dma_id 将四个 proto2 字段打包进 27 位:
bits 0.. 7 : trace_id[0:8] (per-transfer tag low byte)
bits 8..12 : trace_id[8:13] (a & 0x1F00)
bits 13..14 : resource[0:2] (source/descriptor/dest resource, (rsrc & 3) << 13)
bit 15 : node_id[0] (tensor-node selector, (node << 15) & 0x8000)
bits 16..26 : chip_id[0:11] (chip in pod, (chip << 16) & 0x7FF0000)
```text
| 位窗口 | 字段(`EntryDataCase` 3) | 源字段 |
|---|---|---|
| 0..12 | `trace_id` | `field[8]` (+0x20) |
| 13..14 | `resource` | `descriptor_source` `field[32]` (+0x80) |
| 15 | `node_id` | `field[9]` (+0x24) |
| 16..26 | `chip_id` | `field[10]` (+0x28) |
> **怪癖 —** command 与其 data-end 从不同的 proto 字段读取 *resource* 槽位(例如 command 的 `descriptor_source` 对比 data-end 的 `destination_*` 字段),但仍会碰撞,因为主导位(`trace_id` + `node` + `chip`)在二者之间相同。配对不变量(相同 `trace_id` ⇒ 相同 `dma_id`)在这里被解码,但关于 2 位 resource 槽在一对 begin/end 中总是相等的 *证明* 是 firmware emitter 的性质,不是 decoder 的性质(只能在捕获的 trace 上观察)。应把 begin/end 碰撞视为 firmware 契约,而不是 decoder 保证。
---
## HbmMux 频带 — HBM 多路复用器 FSM
### 目的
HbmMux 频带对 HBM 读/写多路复用器计时:它指向 BFIFO 与 Node Fabric 的时长。它是 `EnableBarnaCoreHbmMuxWorkaround` / `SetBarnaCoreHbmMux*ModeTimer` TpuCore 配置在设备端可观测性的对应物;这个 BarnaCore↔HBM mux 被 SparseCore 删除,在这里暴露为单个 XLine(`TpuComponent` 56,`"HBM Mux"`)。
### 入口点
```text
HbmMuxSubscriber<jxc>::ProcessTraceEntry (0xf1def00)
├─ CoreId filter (a1+8)
├─ HbmMuxSwitchState() (0xf6986e0 — returns 0x100000000 | fsm)
├─ fsm in {1,2} -> open marker (store prev entry, set dir)
├─ fsm == 3 -> close BFIFO->NF span (emit, metadata a1+0x20)
└─ fsm == 0 -> close NF->BFIFO span (emit, metadata a1+0x18)算法
fsm 符号是 hbm_mux_switch_trace_entry.fsm(proto field 3,submsg +0x1c)。HbmMuxSwitchState @ 0xf6986e0 在 EntryDataCase == 7 时返回 (0x100000000 | fsm),否则返回 0;bit 32 是 present flag。subscriber 对象保存 +0x28 = prev-entry 指针、+0x30 = 其 refcount handle、+0x38 = 当前打开的方向(0 = none,1 = BFIFO→NF,2 = NF→BFIFO)。
function HbmMuxSubscriber_ProcessTraceEntry(self, entry): // 0xf1def00
if CoreId(entry) != self+8: return
s = HbmMuxSwitchState(entry) // 0xf6986e0
if (s & 0x100000000) == 0: return // not an HbmMux entry
fsm = (uint32)s
if (fsm - 1) < 2: // fsm in {1,2} -> OPEN
self.prev = entry // +0x28
self.refcount = entry.rc // +0x30
self.open_dir = fsm // +0x38 (1 or 2)
return // open marker does NOT emit
if fsm == 3: // CLOSE BFIFO->NF
if self.open_dir != 1: { clear(); return }
start = self.prev.gtc - (DurationCycles(self.prev) << 4)
dur = entry.gtc - start
line = GetOrCreateLine(self.builder, 56) // "HBM Mux"
AddEvent(line, start, dur, self.meta_nf_to_bfifo /*+0x20*/)
clear() // zero +0x28/+0x30, reset +0x38
else if fsm == 0: // CLOSE NF->BFIFO
if self.open_dir != 2: { clear(); return }
start = self.prev.gtc - (DurationCycles(self.prev) << 4)
dur = entry.gtc - start
AddEvent(GetOrCreateLine(self.builder, 56), start, dur,
self.meta_bfifo_to_nf /*+0x18*/)
clear()
```text
> **注意 —** FSM 是一个 **四符号 open/close 机器**,不是二状态 toggle。`{1,2}` 打开一个方向跨度;`{0,3}` 关闭它。状态 3 *不是* 第三个 mux 模式,而是由 `fsm==1` 打开的方向的 close marker,正如 `fsm==0` 关闭由 `fsm==2` 打开的方向。两组配对:
>
> ```text
> fsm 1 = open(BFIFO->NF) ... fsm 3 = close -> emit "Node Fabric to BFIFO" (meta +0x20)
> fsm 2 = open(NF->BFIFO) ... fsm 0 = close -> emit "BFIFO to Node Fabric" (meta +0x18)
> ```
duration 计算从前一 entry 的 GTC 中减去 `DurationCycles(prev) << 4`(cycle→subtick scale,×16)以恢复跨度起点。`DurationCycles` @ `0xf698720` 对 `EntryDataCase` 13/14 读取 `length+0x20`,对 case 12 读取 `+0x24`。两个 close arm 都在 XLine 56 上发射。事件名 metadata 预先构建并缓存:`self+0x18` = `"BFIFO to Node Fabric"`,`self+0x20` = `"Node Fabric to BFIFO"`(字符串存在于 `.rodata`)。
### nf_descriptor — 3 通道 Sync-Flag 载荷
nf band 的更丰富近亲 `nf_descriptor_trace_entry`(`EntryDataCase` 3,27 个字段)携带完整的 src/dst endpoint,以及三个独立的 sync-flag-update 通道和 multicast/segmented flag;这是一个分阶段 Node-Fabric DMA descriptor 在线路上的视图。三个 accessor 暴露 sync-flag 目标,每个都由其通道的 enable 字段控制:
| Accessor | 地址 | Gate 字段 | 打包内容 |
|---|---|---|---|
| `SourceSyncFlagTarget` | `0xf6982e0` | `source_update` (+0x60) | 通过 OCI fold 打包 `{node_id (+0x24), source_update_sync_flag (+0x64)}` |
| `DestinationSyncFlagTarget` | `0xf698340` | `destination_update` (+0x54) | 显式打包(如下) |
| `AckSyncFlagTarget` | `0xf6983a0` | `ack_update` (+0x6c) | 通过 OCI fold 打包 `{node_id (+0x24), ack_update_sync_flag (+0x70)}` |
`SourceSyncFlagTarget` 和 `AckSyncFlagTarget` 将两个 32 位字段加载到 XMM 寄存器的低 quadword,并用 OCI SyncFlag-target packer 折叠(`vpmulld` 对 `xmmword_A2C2560`,`vpand` mask `xmmword_A2D5E00`,然后水平 OR reduction),也就是 OCI 频带使用的同一个 packer。`DestinationSyncFlagTarget` 显式打包:
```text
target = (dest_update_sync_flag (+0x58) & 0x3FF)
| ((dest_update_resource (+0x5c) & 1) << 10)
| ((destination_node_id (+0x40) & 1) << 11)
| ((destination_chip_id (+0x44) << 12) & 0x7FF000)destination 升起一个 "data arrived" flag,source 升起一个 "buffer free" flag,ack 升起一个 "completion" flag;这是跨芯片 Node-Fabric DMA 的三方 sync handshake,是 deepsea OCI descriptor 的 jxc 类比。
brn_perf 频带 — BarnaCore 性能计数器
目的
brn_perf1 和 brn_perf2 是反射驱动的 perf 记录:每个 BarnaCore FSM 操作一条。brn_perf1 剖析三个固定功能 reduce 算子;brn_perf2 剖析十六个 DMA channel controller。字段名不是 StatType enum 条目,而是从嵌入式 proto 字段名取得的内联 GetOrCreateStatMetadata(string_view) 名称;builder 在 V1 converter(ConvertTpuTraceToXPlane<jxc> @ 0xf23f8c0 区域)中通过反射遍历它们。
brn_perf1 — 三个 Reduce 算子
brn_perf1_trace_entry(EntryDataCase 13,id at +0x38)。TracePoint id 和字段名逐字节来自嵌入式 FileDescriptorProto;所有字段名字符串(cycles_of_execution、input0_stall_cycles、input1_stall_cycles、output_stall_cycles、sync_flag_location、is_sync_update)都存在于 .rodata。
| TracePoint | id | XLine (TpuComponent) |
|---|---|---|
CONCAT | 109 (0x6d) | 24 "Barna Core Concat" |
PROCESS_HOSTID | 110 (0x6e) | 25 "Barna Core Process Host ID" |
SPARSE_REDUCE | 111 (0x6f) | 26 "Barna Core Sparse Reduce" |
形状是 2-input / 1-output(input0_stall_cycles、input1_stall_cycles、output_stall_cycles),即 embedding-gather reduce 拓扑:两个 gathered stream 输入,一个 reduced stream 输出。cycles_of_execution 是总运行时间;stall 字段统计被各 stream 阻塞的周期;sync_flag_location + is_sync_update 命名 op 完成时升起的 flag。
brn_perf2 — 十六个 Channel Controller
brn_perf2_trace_entry(EntryDataCase 14,id at +0x38)。与 brn_perf1 相同的 C++ 字段形状,但 stall 拓扑 反转:一个 input stall(input_stall_cycles)和两个 output stall(output0_stall_cycles、output1_stall_cycles);channel controller 拉取一个 descriptor stream 输入,并将其扇出到两个输出队列。
| TracePoint | id 范围 | XLine |
|---|---|---|
CHANNEL0..7 | 100..107 (0x64..0x6b) | 28..35 "Barna Core Channel 0..7" |
PROCESS_BRNID | 108 (0x6c) | 27 "Barna Core Process BRN ID" |
CHANNEL8..15 | 114..121 (0x72..0x79) | 36..43 "Barna Core Channel 8..15" |
Channel n → XLine 28 + n(TpuComponentName cases 28..43 是连续的 "Barna Core Channel 0".."15")。id 范围有一个缺口(107 → 114),由 PROCESS_BRNID(108)在其专属 XLine 27 上桥接;这是 channel burst 前后的 chip-in-pod 路由步骤(确切角色未隔离,推断)。
注意 — 这些频带的存在,是 profiler 层面上 BarnaCore 作为 Jellyfish 上 实时 引擎的指纹:一小组固定融合 reduce 算子、十六个流 channel controller 和一个 HBM mux,全部由硬连线 sync FSM 驱动。SparseCore 替换的正是这些:三个 reduce op 变成 TEC programmable reduce,十六个 channel controller 变成 TAC/TEC stream-gather/scatter 引擎,HBM mux 变成 random-access MMU。
TpuComponentenum 在 v3+ 上保留这些 ordinal,但没有 v3+ trace 会填充它们;这与跨编解码器层可见的“保留 enum,删除实现”的遗留模式相同。
Band → XLine 映射
完整的 jxc DMA/HbmMux/BarnaCore band-to-XLine 分配(TpuComponent 由 TpuComponentName @ 0x1c8ebb60 解码):
TpuComponent | XLine 名称 | Band / 来源 |
|---|---|---|
| 18 | Tensor Core IMEM | nf IMEM cmd/data-end (Dma) |
| 19 | Tensor Core VMEM | nf VMEM↔HBM / VMEM↔ICI (Dma) |
| 20 | Tensor Core SMEM | nf SMEM cmd/data-end (Dma) |
| 24 | Barna Core Concat | brn_perf1 CONCAT(109) |
| 25 | Barna Core Process Host ID | brn_perf1 PROCESS_HOSTID(110) |
| 26 | Barna Core Sparse Reduce | brn_perf1 SPARSE_REDUCE(111) |
| 27 | Barna Core Process BRN ID | brn_perf2 PROCESS_BRNID(108) |
| 28..43 | Barna Core Channel 0..15 | brn_perf2 CHANNEL0..15 |
| 51 | From Host Interface | nf HIB_WRITE_RECEIVE (Dma) |
| 52 | To Host Interface | nf HIB write cmd/data-end (Dma) |
| 56 | HBM Mux | hbm_mux_switch EVENT (HbmMux FSM) |
| 57 | HBM | nf HBM read/write cmd/data-end (Dma) |
基础设施函数
| 函数 | 地址 | 作用 |
|---|---|---|
DmaSubscriber<jxc>::ProcessTraceEntry | 0xf1dfee0 | Dma 频带 span builder + flow stat |
HbmMuxSubscriber<jxc>::ProcessTraceEntry | 0xf1def00 | HbmMux open/close FSM span builder |
GetDmaId | 0xf698180 | 复合 begin/end 配对键 |
MemoryCommand | 0xf698560 | COMMAND gate(mask 0x56B6D8,nf.id ≤ 0x16) |
MemoryDataEnd | 0xf6985a0 | DATA_END gate(mask 0x894920,nf.id ≤ 0x17) |
HbmMuxSwitchState | 0xf6986e0 | fsm 读取(+0x1c),返回 0x100000000 | fsm |
DurationCycles | 0xf698720 | cycle gap(cases 13/14 → +0x20,12 → +0x24) |
GetDmaSize | 0xf6982a0 | 传输大小 length << 10(cases 3/19) |
First / Last | 0xf698620 / 0xf698660 | begin/end marker(cases 5/6/8) |
SourceSyncFlagTarget | 0xf6982e0 | nf_descriptor source sync flag |
DestinationSyncFlagTarget | 0xf698340 | nf_descriptor destination sync flag |
AckSyncFlagTarget | 0xf6983a0 | nf_descriptor ack sync flag |
TpuComponentName | 0x1c8ebb60 | TpuComponent ordinal → XLine name |
GetStatTypeMap | 0x1cf8c660 | StatType 56 = "flow" |
交叉引用
- jxc 旧式载荷 — 生成本页消费的
EntryDataCase/nf.id判别器的 proto2PerformanceTraceEntry分类器(FromTraceEntry) - SparseCore 频带 — BarnaCore reduce/channel-controller profiler 频带在 SparseCore 时代的替代物
- UHI / OCI / ICI DMA 载荷 — deepsea/modern DMA 频带;
GetDmaId和 OCI sync-flag-fold 的跨世代类比 - DMA Endpoint 渲染 — DMA span 和 endpoint 如何呈现在时间线上
- ICR DMA 时间线频带 — 新一代上的姊妹 DMA 时间线频带
- Profiling 概览 — 这些频带接入的 subscriber/XLine 架构