OCI Command DMA-id 选择器
本页中的所有地址均适用于来自
libtpu-0.0.40-cp314wheel 的libtpu.so(构建libtpu_lts_20260413_b_RC00,build-id md589edbbe81c5b328a958fe628a9f2207d)。该镜像未剥离;已反混淆的 C++ 符号名按原文逐字引用。.textVMA 等于文件偏移(.text基址0xe63c000,.rodata基址0x84a0000);.data.rel.ro带有0x200000的 VMA→文件增量。所有地址均为 VMA。其他版本会不同。
摘要
一个 OCI command(off-chip-interconnect command)是单个 device trace event,其中携带最多三个嵌入式 DMA 事务,而不是一个。线上 OCI read/write command 记录保留三个 trace_id_header slot(cmd0 / cmd1 / cmd2),每个 slot 命名一个 DMA 事务的身份,另有一个 index_valid bitmask 表示三个 slot 中哪些是有效的。当 profiler 从这些 command 重建 DMA timeline 时,它必须对每个事务回答一个问题:这个事务由哪个 38-bit dma_id 作为 key,这样 command 的 begin event(例如 OciCommonReadCmdIssuedFromEngine,id 22)才能通过共享 dma_id 与它的 completion event(OciCommonCompletedInTcs,id 96)配对。
这个问题由 CmdDmaIdFromEntry<T> 选择器回答:六个字节相同的模板实例化(每个 OCI command message type T 一个)接收 command message 和一个 int selector(事务索引 0..2),根据 index_valid bitmask 对选择进行门控,读取 trace_id_header_cmd{selector},并从该 header 的 {transaction_id, core_id, chip_id} 组合出 38-bit 复合 dma_id。分发器 TraceEntryWrapper<pxc>::GetDmaId(int) 读取线上 trace_point_id,验证 command 的 protobuf oneof 判别值,并把六个 OCI command id(22、23、26、54、55、96)路由到匹配的 helper;而所有其他(单 header)trace id 会落入一个无 selector 的尾部,从一个内联 trace_id_header 组合出相同的 38-bit 布局。
本页负责三件事,重新实现者必须全部做对:
- 六个
CmdDmaIdFromEntry<T>选择器:每个服务哪个 OCI command,int selector → trace_id_header_cmd{0,1,2}映射(cpp offsetmsg + 0x18 + 8·selector)、index_validbit-selector门控、到TraceIdHeader_globals_默认实例的 null-pointer fallback,以及按字节精确的 38-bitdma_id组合。 - OCI command 携带的三个 header band:
trace_id_header_cmd0/1/2(三个嵌入事务的身份 key,位于 cpp+0x18/+0x20/+0x28)、逐事务index_valid有效 bitmask(+0x30),以及逐事务id_index0/1/2(+0x34/+0x38/+0x3c),它们来自嵌入式FileDescriptorProto池和 parse-table FieldEntry cpp offset。 - id → routing 绑定:
GetDmaId(int)分发(trace_point_id → oneof check → helper)、作为 routing key 的 38-bitdma_id,以及 consumerConvertTpuTraceToXPlane<pxc>如何以它为 key 在absl::flat_hash_map<uint64, DmaTransfer>中配对 begin/end,形成一个 DMA timeline span。consumer 调用GetDmaId(0),即只用 selector 0 /cmd0。
范围 — 四个 id 的 ICR Node-Fabric DMA band decode(ids 48/50/51/91,egress/ingress span 重建)见
../routing/icr-node-fabric-dma.md,这里只链接,不复制。那些 command 暂存的片内描述符见intra-chip-descriptor.md。本页负责 OCI command DMA-id 选择器、command 携带的三个 header band,以及 id→routing 绑定。
| 选择器 | xprof::tpu::CmdDmaIdFromEntry<…pxc::profiler::OciCommon…> — 六个实例化 |
| 选择器 VA | 0xf69a500 / 0xf69a560 / 0xf69a5c0 / 0xf69a620 / 0xf69a680 / 0xf69a6e0(字节相同) |
| 分发器 | TraceEntryWrapper<…pxc::profiler::TraceEntry>::GetDmaId(int) @ 0xf699ca0 |
| OCI command id | 22, 23, 26, 54, 55, 96(线上 trace_point_id) |
| Header band | trace_id_header_cmd0/1/2 @ cpp +0x18/+0x20/+0x28(最多 3 个嵌入事务) |
| 有效门控 | index_valid(uint32,proto f4,cpp +0x30)— 必须设置 bit selector |
dma_id 宽度 | 38 bits = transaction_id[0:21] | (core_id&7)<<21 | (chip_id&0x3fff)<<24 |
| 默认 fallback | …pxc::profiler::TraceIdHeader_globals_(全零 → dma_id == 0) |
| Consumer | ConvertTpuTraceToXPlane<pxc> — GetDmaId(0) @ 0xf26c8d9 → flat_hash_map<uint64, DmaTransfer> |
| 证据等级 | 可重新实现级 / 已确认(按字节锚定于 IDA 反编译 + FDP 池) |
1. OCI command 作为带嵌入 DMA 事务的 command 记录
OCI command band 是 deepsea read/write COMMAND trace:由一个引擎向 off-chip interconnect 发出的 command,在其旅程中的多个点被观测到(issued from engine、accepted at the memory node、completed at the TensorCore Sequencer)。关键结构事实是:一个 command event 编码一到三个 DMA 事务,每个事务由自己的 trace_id_header 标识。
六个 OCI command message 类共享一个 protobuf schema;该 schema 在六者之间按字节完全一致,并已同时对照 FileDescriptorProto 字段列表和 parse-table FieldEntry cpp offset 交叉检查:
| proto # | 字段名 | 类型 | cpp off | wire tag | 角色 |
|---|---|---|---|---|---|
| 1 | trace_id_header_cmd0 | message | 0x18 | 0x0a | 嵌入式 DMA 事务 #0 身份(band 0) |
| 2 | trace_id_header_cmd1 | message | 0x20 | 0x12 | 嵌入式 DMA 事务 #1 身份(band 1) |
| 3 | trace_id_header_cmd2 | message | 0x28 | 0x1a | 嵌入式 DMA 事务 #2 身份(band 2) |
| 4 | index_valid | uint32 | 0x30 | 0x20 | 逐事务有效 bitmask(bit N = cmdN live) |
| 5 | id_index0 | uint32 | 0x34 | 0x28 | 事务 #0 id-index(线上 17-bit) |
| 6 | id_index1 | uint32 | 0x38 | 0x30 | 事务 #1 id-index |
| 7 | id_index2 | uint32 | 0x3c | 0x38 | 事务 #2 id-index |
| 8 | node_type | enum | 0x40 | 0x40 | command 端点类别(NodeTypeValues) |
Message 布局:vtable
@0,InternalMetadata@0x8,hasbits@0x10,三个 submessage pointercmd0/cmd1/cmd2@0x18/0x20/0x28,index_valid@0x30,id_index0/1/2@0x34/0x38/0x3c,node_type@0x40。dtor 精确释放+0x18/+0x20/+0x28处的三个 submessage pointer(每个都是TraceIdHeader);ctor 将0x10..0x43清零,因此三个 pointer 起始为 null。这些 offset 正是选择器的读取位置(§2)。
三个 trace_id_header_cmd0/1/2 是本页负责的三个 header band。每一个都是 command 触发的一个 DMA 事务的身份。index_valid bitmask 表示三个 band 中哪些已填充:发出单个 DMA 的 command 只设置 bit 0;扇出到三个事务的 command 设置 bit 0、1、2。id_index0/1/2 是 17-bit 逐事务索引(它们的确切作用是 queue slot、descriptor-ring pointer 还是 re-order tag,不属于 dma_id key;见 §6)。
1.1 嵌入式 TraceIdHeader(逐事务身份)
三个 header band 中每个都是一个 TraceIdHeader submessage。它的三个字段是 38-bit dma_id 的唯一来源:
| proto # | 字段名 | 类型 | cpp off | wire tag | dma_id bits |
|---|---|---|---|---|---|
| 1 | transaction_id | uint32 | 0x18 | 0x08 | [0:21] |
| 2 | core_id | enum | 0x1c | 0x10 | [21:24] (& 7) |
| 3 | chip_id | uint32 | 0x20 | 0x18 | [24:38] (& 0x3fff) |
core_id 是 TraceIdHeaderCoreIdValues(pxc / BarnaCore 代际):0=RESERVED, 1=NONCORE, 2=TC0, 3=TC1, 4=BC0, 5=BC1, 6=BC2, 7=BC3。SparseCore 代际会用 SC0..SC3 替换 BC0..BC3(跨代重命名);字段宽度和 & 7 mask 不变。
node_type 是 NodeTypeValues,即 command 端点类别:
0 = NODE_TYPE_TCS 1 = NODE_TYPE_BC 2 = NODE_TYPE_CMQ 3 = NODE_TYPE_HBMQ
4 = NODE_TYPE_UHI 5 = NODE_TYPE_ICR 6 = NODE_TYPE_QNM
```text
> **注意 —** `node_type` 标记 command 的端点(哪个片上 node 类发出/接收它),是 payload 字段,**不是** `dma_id` key 的一部分,也**不会**被选择器读取。同一个枚举也出现在 OCI-message band 上;见 [`../routing/icr-node-fabric-dma.md`](../routing/icr-node-fabric-dma.md) §2.2。
---
## 2. 六个 `CmdDmaIdFromEntry<T>` 选择器
每个 OCI command message type `T` 都有一个 `CmdDmaIdFromEntry<T>(const T& msg, int selector)` 模板实例化。所有六个函数体都**按字节相同**:同一个 C++ 模板被发出六次,差异只在模板名 relocation 和每个 type 的 `*_globals_` 默认实例地址。选择器回答的问题是:*“如果该事务有效,请给出此 command 的第 `selector` 个嵌入式 DMA 事务的 `dma_id`。”*
| selector VA | template type `T`(OCI command message) | 线上 id | `oneof`(proto f,位于 `entry+0x28`) |
|-------------|------------------------------------------|------------|------------------------------------|
| `0xf69a500` | `OciCommonReadCmdIssuedFromEngine` | 22 | 15 |
| `0xf69a560` | `OciCommonMemReadReqFromEngine` | 23 | 16 |
| `0xf69a5c0` | `OciCommonWriteCmdAcceptedAtMn` | 26 | 19 |
| `0xf69a620` | `OciCommonOciWriteCommand` | 54 | 35 |
| `0xf69a680` | `OciCommonOciReadCommand` | 55 | 36 |
| `0xf69a6e0` | `OciCommonCompletedInTcs` | 96 | 53 |
> 六个反编译函数体逐字节相同。函数体如下(展示 selector `0xf69a500`;其他五个仅 `T` 和 `*_globals_` 地址不同):
```c
// CmdDmaIdFromEntry<…OciCommonReadCmdIssuedFromEngine>(a1 = const T& msg, a2 = int selector)
unsigned __int64 CmdDmaIdFromEntry(__int64 a1, unsigned int a2)
{
// index_valid (uint32 @msg+0x30) >> selector
unsigned __int64 v3 = (unsigned __int64)*(unsigned int *)(a1 + 48) >> a2;
unsigned __int64 result = 0; // present = 0 (absent)
if ( a2 <= 2 && (v3 & 1) != 0 ) // selector in 0..2 AND index_valid bit set
{
// trace_id_header_cmd{selector} pointer @ msg + 0x18 + 8*selector
TraceIdHeader **v5 = *(TraceIdHeader ***)(a1 + 8LL * a2 + 24);
if ( !v5 )
v5 = &TraceIdHeader_globals_; // null submessage → all-zero default instance
return ((_DWORD)v5[3] & 0x1FFF00) // transaction_id[8:21] (header +0x18)
| (( *((_DWORD *)v5 + 7) & 7u) << 21) // core_id[0:3] << 21 (header +0x1c)
| ((unsigned __int64)((_DWORD)v5[4] & 0x3FFF) << 24) // chip_id[0:14] << 24 (header +0x20)
| (unsigned __int8)*((_DWORD *)v5 + 6); // transaction_id[0:8] (header +0x18)
}
return result; // selector > 2 OR bit clear → present = 0
}结果会包装在 std::optional<unsigned long> 中:组合出的 38-bit 值加上 presence bit(组合路径上 dl = 1,absent 路径上为 0)。absent 结果会导致 consumer 丢弃该 entry(它不是 DMA 配对事件)。
2.1 selector → trace_id_header 映射
int selector 是事务索引。它通过对 message 做简单 pointer arithmetic 来索引三个 header band:
| selector | 选择字段 | proto # | cpp offset (msg + 0x18 + 8·sel) | 含义 |
|---|---|---|---|---|
| 0 | trace_id_header_cmd0 | f1 | msg + 0x18 | 第 1 个嵌入式 DMA 事务 |
| 1 | trace_id_header_cmd1 | f2 | msg + 0x20 | 第 2 个嵌入式 DMA 事务 |
| 2 | trace_id_header_cmd2 | f3 | msg + 0x28 | 第 3 个嵌入式 DMA 事务 |
| ≥ 3 | (越界) | — | — | 返回 absent(present = 0) |
边界 a2 <= 2 会在使用索引前拒绝 0..2 以外的任何 selector,因此 8·selector 索引只能访问三个 header slot。
2.2 index_valid 门控
rsi = msg.index_valid (uint32 @ msg+0x30)
rsi >>= selector
if (rsi & 1) == 0 → return absent (present = 0)
```text
`index_valid`(proto f4)是逐事务有效 bitmask:bit N 表示“事务 N 存在,且 `trace_id_header_cmd{N}` 有意义”。携带一个 DMA 的 command 设置 bit 0;扇出到三个事务的 command 设置 bit 0/1/2。如果请求的 `selector` 对应 bit 未置位,选择器返回 absent,事务被丢弃,即使 command 记录在物理上为全部三个 header slot 预留了空间。
### 2.3 null-pointer fallback
如果 `index_valid` bit `selector` *已*设置,但 `cmd{selector}` submessage pointer 为 null(`msg[+0x18 + 8·sel] == 0`),选择器会替换为 proto-runtime 默认实例 `…pxc::profiler::TraceIdHeader_globals_`。该块全为零,因此组合出的 `dma_id` 为 0(且 `present = 1`)。实践中,置位的 valid-bit 意味着已构造 submessage;这是 protobuf 默认实例安全路径,用来保证读取是全函数的。
> **注意 —** 选择器会**两次**读取 header 的 `transaction_id` 来跨字节边界组装 21-bit 字段:`(transaction_id & 0x1FFF00)` 覆盖 bits `[8:21]`,`(uint8)transaction_id` 覆盖 bits `[0:8]`。朴素地读一次 `transaction_id & 0x1FFFFF` 是等价且更简单的;二进制中的两次读取形式是编译器产物,不是语义差异。重新实现者应把 `transaction_id` 当成一个单独的 21-bit 字段。
---
## 3. 38-bit 复合 `dma_id`(routing key)
选择器从选中的 header 的三个字段组合出一个 38-bit 标识符。这个复合值是 **routing key**,即决定事务落入哪个 timeline slot、从而决定哪个 begin event 与哪个 end event 配对的值。
```text
dma_id = (transaction_id & 0x1FFFFF) // bits [0:21] 21-bit per-transaction txn id
| ((core_id & 0x7) << 21) // bits [21:24] 3-bit core_id enum
| ((chip_id & 0x3FFF) << 24) // bits [24:38] 14-bit chip id
present = 1| 字段 | 来源(header offset) | mask | shift | id bits |
|---|---|---|---|---|
transaction_id | +0x18 | 0x1FFFFF | 0 | [0:21] |
core_id | +0x1c | 0x7 | 21 | [21:24] |
chip_id | +0x20 | 0x3FFF | 24 | [24:38] |
chip-id 字段在这个 pxc build 中宽 14 bits(& 0x3FFF);早期代际使用更窄的(12-bit)chip id,后续硅片扩大到 14 bits。完整结果为 38 bits。这与 ICR Node-Fabric DMA band 对其单 header dma_id 提取使用的 bit 布局相同:OCI command 选择器和 NF-band 提取器会收敛到一种复合 ID 格式,因此一个事务的 id 可以跨两个 band 比较。
按字节精确的组合出现在两个地方:每个
CmdDmaIdFromEntry<T>选择器(§2 函数体),以及用于单 header trace id 的GetDmaId(int)无 selector 尾部(LABEL_172,§4)。二者都读取 header+0x18处的transaction_id、+0x1c处的core_id、+0x20处的chip_id,并发出相同的0x1FFF00 | (core_id&7)<<21 | (chip_id&0x3fff)<<24 | (uint8)transaction_id表达式。
4. 分发器:GetDmaId(int)(id → selector → routing key)
TraceEntryWrapper<…pxc::profiler::TraceEntry>::GetDmaId(int) @ 0xf699ca0 是把一个 live trace entry 转换为 dma_id 的入口。它解引用 wrapper 到达底层 TraceEntry(v2 = *(entry + 0x10)),从 trace header(+0x18)读取线上 trace_point_id,并对其 switch(0x96 arm jump table,经过 ≤ 0x95 边界检查,default → return 0)。
这个 switch 有两类 arm:
(a) 六个 OCI command arm。 对 id 22/23/26/54/55/96,arm 会验证 protobuf oneof 判别值(*(v2 + 0x28) == <oneof>),加载 live command-payload submessage pointer(v2 + 0x20),或在 oneof 不匹配时使用该 command 的 *_globals_ 默认实例,然后尾调用匹配的 CmdDmaIdFromEntry<T> 选择器,把原始 int 参数作为 selector 转发:
case 22: // OciCommonReadCmdIssuedFromEngine
if ( *(_DWORD *)(v2 + 40) == 15 ) // oneof case 15 active?
v7 = *(...*)(v2 + 32); // live command payload (entry+0x20)
else
v7 = &OciCommonReadCmdIssuedFromEngine_globals_; // default instance
return CmdDmaIdFromEntry<…OciCommonReadCmdIssuedFromEngine>(v7, a2 /* selector */);
case 55: // OciCommonOciReadCommand
if ( *(_DWORD *)(v2 + 40) == 36 )
v9 = *(...*)(v2 + 32);
else
v9 = &OciCommonOciReadCommand_globals_;
return CmdDmaIdFromEntry<…OciCommonOciReadCommand>(v9, a2);
// …id 23 (oneof 16), id 26 (oneof 19), id 54 (oneof 35), id 96 (oneof 53) identical shape
```text
**(b) 单 header 尾部。** 每个*其他* trace id(OCI/UHI/CMQ/ICI/NF 单 header event,以及 ICR band id 48/50/51/91)都在 entry-submessage 的 `+0x18` 处携带正好一个内联 `TraceIdHeader`。这些 arm 会加载该 header(或每个 id 对应的 `*_globals_`,或最终在 null 时使用 `TraceIdHeader_globals_`),然后落入公共尾部 `LABEL_172`,组合出与 §3 **相同**的 38-bit 布局。该尾部是选择器组合的无 selector twin。
```c
LABEL_172:
v3 = *((_DWORD *)v6 + 6); // transaction_id (header +0x18)
v4 = ((unsigned int)v3 & 0x1FFF00)
| ((*((_DWORD *)v6 + 7) & 7) << 21) // core_id (header +0x1c)
| ((unsigned __int64)((_DWORD)v6[4] & 0x3FFF) << 24); // chip_id (header +0x20)
return v4 | (unsigned __int8)v3;线上 id →
oneof映射(id 22 → 15,23 → 16,26 → 19,54 → 35,55 → 36,96 → 53)精确匹配 OCI commandoneof字段号,并且每个 arm 都把entry+0x20(live payload)/*_globals_(fallback)转发到选择器。default arm 返回 0(absent)。
5. id → routing 绑定(consumer)
GetDmaId(int) 在该单元中只有一个调用者:ConvertTpuTraceToXPlane<…pxc::profiler::TraceEntry> @ 0xf26c8d9,这一点由完整 .text rel32 扫描证明。调用者以 selector 0 调用它:
DmaId = TraceEntryWrapper<…pxc::profiler::TraceEntry>::GetDmaId(v14, 0); // selector 0 = cmd0
// test presence bit; if absent → drop (not a DMA-pairing event)
// else: DmaId is the key into flat_hash_map<uint64, DmaTransfer>
```text
38-bit `dma_id` 作为 key 进入 `absl::flat_hash_map<unsigned long, xprof::tpu::(anon)::DmaTransfer>`(policy `FlatHashMapPolicy<unsigned long, DmaTransfer>`;通过 `PrepareInsertSmallNonSoo` / `PrepareInsertLarge` 插入;key 由 `Hash<long>` 哈希)。共享同一 `dma_id` 的 begin 和 end event 会落入**同一个** `DmaTransfer` slot,生成一个 begin/end span。该 map 随后由 `MergeOverlappingTransfers` → `ConvertDmaTransfersToXPlane` 排空为 device XEvent。
这就是 *routing*:`dma_id` 把 command 的事务路由到单个 timeline slot,从而:
```text
OciCommonReadCmdIssuedFromEngine (id 22) ── begin marker ─┐
├─ same dma_id → one DmaTransfer span
OciCommonCompletedInTcs (id 96) ── end marker ───┘已确认-部分 — consumer 只以
cmd0为 key。GetDmaId(int)在这里恰好从唯一调用点被调用,且始终使用selector = 0。selector 模板支持selector 1/2(可提取第 2/第 3 个嵌入事务的dma_id),但该单元中没有 consumer 请求它们:multi-transaction OCI command 是否曾由不同 pass(或更新代际 builder)拆成多个 timeline span,在该二进制中未验证。pxc DMA timeline 以第一个嵌入事务的dma_id配对。
5.1 这里与 ICR Node-Fabric band 的差异
OCI command band(本页)和 ICR Node-Fabric DMA band(../routing/icr-node-fabric-dma.md)是进入同一个 flat_hash_map<uint64, DmaTransfer> 机制的两条不同路径,但它们由不同代码读取:
| OCI command band(本页) | ICR Node-Fabric DMA band | |
|---|---|---|
| Trace ids | 22, 23, 26, 54, 55, 96 | 48, 50, 51, 91 |
| 每个 event 的 header 数 | 最多 3 个(cmd0/1/2,由 index_valid 门控) | 正好 1 个(内联 trace_id_header) |
dma_id 提取器 | CmdDmaIdFromEntry<T>(msg, selector) | GetDmaId 每 id arm → 单 header 尾部 |
| Begin/end 配对 | command issued (22/26) ↔ completed (96),相同 dma_id | descriptor (91) / egress-msg (50);ICI first/last packet (48) |
| 负责内容 | command DMA-id 选择器 + 3 个 header band + id→routing | 48/50/51/91 payload decode + egress/ingress span |
二者使用完全相同的 38-bit dma_id 布局(§3)和相同的 flat_hash_map policy,因此无论一个事务是在 command band 还是 NF band 上被观测到,它的 id 都是同一个值;这正是让两个 band 中属于同一事务的 event 能够归并的原因。
6. 选择器不决定什么
注意 — 选择器只读取所选 header 的
{transaction_id, core_id, chip_id}和index_valid门控。OCI command 记录上的其他所有内容都会被 selector 路径丢弃:
id_index0/1/2(+0x34/+0x38/+0x3c处的 17-bit 逐事务索引)会被解码进 proto,但不是dma_idkey 的一部分。它们的语义角色,即 command-queue slot、descriptor-ring pointer,还是区别于transaction_id的 re-order tag,在这里为 LOW / unverified;没有定位到将其作为 timeline key 读取的 consumer。node_type(+0x40)标记端点类别,但不选择 lane,也不作为 slot 的 key。DmaTransfer配对内部的 begin/end 判别,即哪个trace_point_id标记一个 span 的 begin(id 22/26)与 end(id 96),以及MergeOverlappingTransfers如何折叠相同dma_id的 event,是DmaTransfer结构自身的逻辑,不是选择器的逻辑;它随 band decode 记录,而不是记录在这里。
这些六个选择器的逐代(vfc/vlc/glc/gfc)等价物不在范围内:这里的 GetDmaId(int) 是 pxc-template 实例化;新代际是否发出自己的 CmdDmaIdFromEntry<gen::profiler::OciCommon…> 选择器(带原生 14-bit chip id 和 SparseCore core_id 重命名),或以不同方式折叠 command DMA band,均未验证;这里没有搜索逐代选择器符号。
7. 参考偏移
OCI command message(
OciCommonOciReadCommand及其五个 sibling,schema 相同):vtable@0,InternalMetadata@0x8,hasbits@0x10,trace_id_header_cmd0@0x18/cmd1@0x20/cmd2@0x28(submessage ptr),index_valid@0x30,id_index0/1/2@0x34/0x38/0x3c,node_type@0x40。dtor 释放三个cmd*submessage(每个都是TraceIdHeader,alloc0x28B);ctor 将0x10..0x43清零(三个 ptr 起始为 null)。
TraceIdHeader(pxc):transaction_id@0x18·core_id@0x1c·chip_id@0x20。默认 prototype…pxc::profiler::TraceIdHeader_globals_(全零 →dma_id == 0)。**关键位置:**六个选择器
0xf69a500/0xf69a560/0xf69a5c0/0xf69a620/0xf69a680/0xf69a6e0(字节相同)· 分发器GetDmaId(int)0xf699ca0(jump table0x96arms,bound0x95,default-drop)· 分发器内的 OCI command arm:id 22(oneof15)、id 23(16)、id 26(19)、id 54(35)、id 55(36)、id 96(53)· 单 header 尾部LABEL_172· consumerConvertTpuTraceToXPlane<pxc>GetDmaId(0)调用点0xf26c8d9(单一调用者)·flat_hash_map<uint64, DmaTransfer>insertPrepareInsertSmallNonSoo/PrepareInsertLarge。
dma_id布局:transaction_id[0:21] (0x1FFFFF)|core_id[21:24] (&7 <<21)|chip_id[24:38] (&0x3fff <<24)→ 38 bits。
交叉引用
../routing/icr-node-fabric-dma.md— 四个 id 的 ICR Node-Fabric DMA band(48/50/51/91):共享相同 38-bitdma_id和flat_hash_map<uint64, DmaTransfer>机制的 payload decode 与 egress/ingress span 重建。../routing/nf-descriptor.md— cross-chip 事务暂存的线上 Node-Fabric DMA 描述符记录。intra-chip-descriptor.md— 片内OciDescriptorCommonIssuedFromTcs描述符:OCI command 的事务所引用的片上 DMA。rolled-strided-general.md— 填充这些描述符的 rolled / strided / general 传输体发射器。host-device-dma.md— host↔device DMA 路径(MemcpyH2D/MemcpyD2Hlane),一个 sibling timeline band。uhi-host-interface.md— UHI host-interface band(NODE_TYPE_UHI),另一个 OCI 端点类别。