Skip to content

jxc DMA / HbmMux / brn_perf 频带

本页所有地址适用于 libtpu.so v0.0.40(libtpu-0.0.40-cp314,build-id 89edbbe81c5b328a958fe628a9f2207d)。.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 显示名,以及 flow XStat 值公式。
  • GetDmaId 复合键:用于把 begin 与 end 配对的精确 OR/shift 位布局,以及哪些 proto2 字段馈入每个位窗口。
  • HbmMux FSM:四个 fsm 符号、open/close 配对,以及由两份 metadata 选择的事件名。
  • nf_descriptor 3 通道 sync-flag 载荷,以及 brn_perf1/brn_perf2 字段表及其按 id 分配的 XLine。
Dma subscriberxprof::tpu::DmaSubscriber<jxc::PerformanceTraceEntry>::ProcessTraceEntry @ 0xf1dfee0
HbmMux subscriberxprof::tpu::HbmMuxSubscriber<jxc::PerformanceTraceEntry>::ProcessTraceEntry @ 0xf1def00
DMA-id composerTraceEntryWrapper<jxc>::GetDmaId @ 0xf698180
COMMAND / DATA_END gateMemoryCommand @ 0xf698560 (mask 0x56B6D8) / MemoryDataEnd @ 0xf6985a0 (mask 0x894920)
Flow statStatType 56 = "flow";值 ((dma_id & 0x00FFFFFFFFFFFFFF) << 2) | 3
HbmMux XLineTpuComponent 56 = "HBM Mux"TpuComponentName @ 0x1c8ebb60
Record discriminatorsubmsg-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 承载。

入口点

text
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_END trace-point id 关闭跨度,会错误处理 read 路径(它们从不携带 "Write" 名称)以及 "Receive" HIB 路径(kind 7)。判别器是按 arm 设置的 label

按引擎映射

十七个 DMA edge 解析为六个 XLine。XLine 是一个 TpuComponent ordinal,由 TpuComponentName @ 0x1c8ebb60 解码;显示名 blob 位于 off_21643E10/E20/E30R_X86_64_RELATIVE addend → "Receive"/"Read"/"Write")。

arm (nf.id)事件XLine显示名kind
0 (3)HBM_READ_COMMAND57 "HBM"Read4
1 (4) / 2 (5)HBM_WRITE cmd / data-end57 "HBM"Write5
3 (6) / 4 (7) / 5 (8)VMEM↔HBM read/write cmd / data-end19 "Tensor Core VMEM"Read/Write4/5
6 (9) / 7 (10) / 8 (11)VMEM↔ICI read/write cmd / data-end19 "Tensor Core VMEM"Read/Write4/5
9 (12) / 10 (13) / 11 (14)SMEM read/write cmd / data-end20 "Tensor Core SMEM"Read/Write4/5
12 (15) / 13 (16)IMEM write cmd / data-end18 "Tensor Core IMEM"Write5
17 (20)HIB_WRITE_RECEIVE51 "From Host Interface"Receive7
19 (22) / 20 (23)HIB write cmd / data-end52 "To Host Interface"Write5

注意 — nf.id 17/18/19(BMEM)和 27(ICI_SEND_END)的 switch arm 会路由到 drop 出口;BMEM 有 GetDmaId composer,但 Dma subscriber 从不注册它。Reads(First)打开一个 pending begin;匹配的 write/receive DATA_ENDLast)关闭它。一次传输的 byte count 在 flow stat 中;它可通过 GetDmaSize @ 0xf6982a0 单独取得(length << 10,1 KiB 单位;EntryDataCase 3 读取 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)。该值以内联方式构造:

text
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 位:

text
  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 @ 0xf6986e0EntryDataCase == 7 时返回 (0x100000000 | fsm),否则返回 0;bit 32 是 present flag。subscriber 对象保存 +0x28 = prev-entry 指针、+0x30 = 其 refcount handle、+0x38 = 当前打开的方向(0 = none,1 = BFIFO→NF,2 = NF→BFIFO)。

c
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` 327 个字段)携带完整的 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_perf1brn_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_entryEntryDataCase 13,id at +0x38)。TracePoint id 和字段名逐字节来自嵌入式 FileDescriptorProto;所有字段名字符串(cycles_of_executioninput0_stall_cyclesinput1_stall_cyclesoutput_stall_cyclessync_flag_locationis_sync_update)都存在于 .rodata

TracePointidXLine (TpuComponent)
CONCAT109 (0x6d)24 "Barna Core Concat"
PROCESS_HOSTID110 (0x6e)25 "Barna Core Process Host ID"
SPARSE_REDUCE111 (0x6f)26 "Barna Core Sparse Reduce"

形状是 2-input / 1-outputinput0_stall_cyclesinput1_stall_cyclesoutput_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_entryEntryDataCase 14,id at +0x38)。与 brn_perf1 相同的 C++ 字段形状,但 stall 拓扑 反转:一个 input stall(input_stall_cycles)和两个 output stall(output0_stall_cyclesoutput1_stall_cycles);channel controller 拉取一个 descriptor stream 输入,并将其扇出到两个输出队列。

TracePointid 范围XLine
CHANNEL0..7100..107 (0x64..0x6b)28..35 "Barna Core Channel 0..7"
PROCESS_BRNID108 (0x6c)27 "Barna Core Process BRN ID"
CHANNEL8..15114..121 (0x72..0x79)36..43 "Barna Core Channel 8..15"

Channel n → XLine 28 + nTpuComponentName 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。TpuComponent enum 在 v3+ 上保留这些 ordinal,但没有 v3+ trace 会填充它们;这与跨编解码器层可见的“保留 enum,删除实现”的遗留模式相同。


Band → XLine 映射

完整的 jxc DMA/HbmMux/BarnaCore band-to-XLine 分配(TpuComponentTpuComponentName @ 0x1c8ebb60 解码):

TpuComponentXLine 名称Band / 来源
18Tensor Core IMEMnf IMEM cmd/data-end (Dma)
19Tensor Core VMEMnf VMEM↔HBM / VMEM↔ICI (Dma)
20Tensor Core SMEMnf SMEM cmd/data-end (Dma)
24Barna Core Concatbrn_perf1 CONCAT(109)
25Barna Core Process Host IDbrn_perf1 PROCESS_HOSTID(110)
26Barna Core Sparse Reducebrn_perf1 SPARSE_REDUCE(111)
27Barna Core Process BRN IDbrn_perf2 PROCESS_BRNID(108)
28..43Barna Core Channel 0..15brn_perf2 CHANNEL0..15
51From Host Interfacenf HIB_WRITE_RECEIVE (Dma)
52To Host Interfacenf HIB write cmd/data-end (Dma)
56HBM Muxhbm_mux_switch EVENT (HbmMux FSM)
57HBMnf HBM read/write cmd/data-end (Dma)

基础设施函数

函数地址作用
DmaSubscriber<jxc>::ProcessTraceEntry0xf1dfee0Dma 频带 span builder + flow stat
HbmMuxSubscriber<jxc>::ProcessTraceEntry0xf1def00HbmMux open/close FSM span builder
GetDmaId0xf698180复合 begin/end 配对键
MemoryCommand0xf698560COMMAND gate(mask 0x56B6D8nf.id ≤ 0x16
MemoryDataEnd0xf6985a0DATA_END gate(mask 0x894920nf.id ≤ 0x17
HbmMuxSwitchState0xf6986e0fsm 读取(+0x1c),返回 0x100000000 | fsm
DurationCycles0xf698720cycle gap(cases 13/14 → +0x20,12 → +0x24
GetDmaSize0xf6982a0传输大小 length << 10(cases 3/19)
First / Last0xf698620 / 0xf698660begin/end marker(cases 5/6/8)
SourceSyncFlagTarget0xf6982e0nf_descriptor source sync flag
DestinationSyncFlagTarget0xf698340nf_descriptor destination sync flag
AckSyncFlagTarget0xf6983a0nf_descriptor ack sync flag
TpuComponentName0x1c8ebb60TpuComponent ordinal → XLine name
GetStatTypeMap0x1cf8c660StatType 56 = "flow"

交叉引用