Skip to content

TracePoints 主注册表

本页中的所有地址、id 和偏移均适用于来自 libtpu-0.0.40-cp314 wheel 的 libtpu.so(build-id 89edbbe81c5b328a958fe628a9f2207d)。该二进制文件剥离符号,完整 C++ 符号存在,且 .text VMA 等于文件偏移。其他版本会有所不同。

摘要

本页是 libtpu 设备端 profiler 的主 trace-point id→name 注册表:这张表把每个线上 trace_point_idcodec 解码的 8 位 TraceHeader 字段)映射到人类可读的事件名、其所属硬件 band,以及消费它的 subscriber。它是 decode → XSpace 扇出的索引:当 DecodeTraceBuffers 遍历一个 16 字节 packet 时,它读到的线上 trace_point_id 只是一个数字;这个数字的含义,即它命名哪个事件、落到哪条设备 line、由哪组 begin/end tracker 配对,都在这里定义。

注册表不是二进制中的静态表。它由 ConvertTpuTraceToXPlaneV2<TraceEntry>(204 个符号引用)在运行时构建;该函数第一次看到每个片上 core 时,会运行对应 family 的 CoreContext setup lambda,注册固定集合的 TraceEventSubscriber,每个 subscriber 都带有一个内联的 TracePoints<TraceEntry> int32 id 集。CoreDispatcher::RegisterSubscriber(每个 chip family 一个 out-of-line 符号,共 6 个)把每个 subscriber 插入 FlatHashMap<trace_point_id, vector<subscriber>>。id→name 映射本身是 codec 的逐事件 Decode<EventName>() 跳转表;主注册表则是该命名空间与 lambda 在其上安装的 subscriber 路由的并集。要逐字节精确重建它,必须同时读取两者:codec 的 111 项 decode 名称表,以及各 family lambda 为每个 subscriber 选择的 id-set。

id 空间是分 band的。deepsea 各代(pxc/vfc/vlc/glc/gfc)把 trace_point_id 打包到一个有空洞的 0..255 空间中,并按硬件来源分区:UHI host-bridge、OCI 片上互连、ICI 片间互连、DMA、base 80 的 TensorCore sync/fence band、base 109 的 SparseCore band、base 104/200 的 throttle band,以及 base 160 的 MGR/power band。旧式 jxc(jellyfish)一代使用完全不同的 16 位 id 命名空间。本页负责按 band 汇总 id→name/subscriber/tracker;按 band 的payload 字段解码由 payload 页面负责,id→name codec 分发TraceEntriesCoder 负责。

对于重新实现,契约是:

  • deepsea 0..255 trace_point_id 空间的 band 分区:每个硬件来源拥有哪个连续 id 范围,以及它的 band base。
  • 每个 band 的 id→name 映射:codec 的 Decode<Name>() 附加到每个 id 的事件名(每个 decode/translation 步骤依赖的 wire→human 映射)。
  • id→subscriber 扇出:CoreContext lambda 安装的 FlatHashMap 路由;一个 id 可以驱动 N 个 subscriber 的结构事实(id 85 → 4)。
  • begin/end tracker 匹配键:哪些 id 输入哪些有状态 tracker(Step/Task/Overlay/Sync/Dma),以及它用哪个字段配对 span。
注册表构建器xprof::tpu::ConvertTpuTraceToXPlaneV2<TraceEntry> — pxc @0xf1d4360(+5 个 family)
CoreContext setup lambdapxc @0xf1eb2e0, gfc @0xf229100, glc @0xf214640, vfc @0xf201bc0, vlc @0xf1f5940, jxc @0xf1da7c0
路由结构CoreDispatcher FlatHashMap<trace_point_id (u16 @ TraceHeader+0x18), vector<shared_ptr<TraceEventSubscriber>>>
注册调用CoreDispatcher::RegisterSubscriber(this, const TracePoints&, shared_ptr<sub>) — pxc @0xf1ecee0(+5)
分发(drain)CoreDispatcher::Dispatch @0xf1ed280movzwl 0x18(%rax),%edx 读取 id,call *0x10(vtable) 扇出
Id→name 来源通过 111 项 rel32 跳转表 @0xab85bc0 的逐事件 Decode<Name>()codec
Subscriber 数量 / familypxc 8 · gfc 19 · glc 19 · vfc 17 · vlc 11 · jxc 10

速览 — band 及其 id 范围

BandBase / 范围(deepsea)来源SubscriberPayload 页面
UHIOCI sub-channel (*UhiBridge)Host bridge(raw path)uhi-oci-ici-dma
OCIOciMessage*(20 个事件)片上互连(raw path)uhi-oci-ici-dma
ICIIciPacket*片间互连(raw path)uhi-oci-ici-dma
DMACMQ/CMN/HDE req+data-endDMA 引擎DmaSubscriber(jxc)uhi-oci-ici-dma
Sync/Fencebase 80(80..90)TensorCoreSync + ScalarFence ×2sc-band / vfc-vlc-gfc
Throttlebase 104(vfc/vlc)/ 200(gfc/glc)电源管理PowerThrottlevfc-vlc-gfc
SparseCorebase 109(109..120)SparseCore6 个 SC subscribersc-band
MGR/Powerbase 160 + 168/169MGR firmwarePState/Firmware/Spivfc-vlc-gfc
BarnaCorepxc — 无 SC band仅 pxc(仅 TC 扇出)jxc-legacy
jxc legacy16 位 jellyfish nsjellyfish genHbmMux + Dma + 8jxc-legacy

NOTE — “raw path” 表示该 band 在 deepsea CoreContext lambda 中没有专用 subscriber。UHI/OCI/ICI id 会落到 raw TraceEventSubscriber 十进制字符串 XEvent 路径(FastIntToBuffer 名称回退),而不是语义化 subscriber。参见 § 未绑定 band。下方的名称仍然是权威 codec decode 名称;缺失的是路由。


id 如何变成事件

注册机制

注册表是惰性组装的。ConvertTpuTraceToXPlaneV2<TraceEntry> 启动一个工作线程,并在第一次看到某个 ChipCoreId 时运行该 family 的 CoreContext setup lambda({lambda(shared_ptr<TraceEntryWrapper>)}::operator())。该 lambda 构建每个 core 的 TpuXPlaneBuilder,然后执行 N 次 RegisterSubscriber 调用;N 是每个 family 的 subscriber 数量(8/19/19/17/11/10)。

c
// CoreContext setup lambda — schematic of one register call
// (pxc @0xf1eb2e0; one of 8 such blocks)
function RegisterOne(dispatcher, kind, id_set[], n, line):
    sub = operator_new(...)                  // allocate the subscriber
    sub.vtable = SubscriberVtable[kind]       // or call its out-of-line ctor
    // most subscribers are wrapped in a ThreadedSubscriber (vtable + ClosureThread
    // worker @0xf1ede60 at +0xa0); HLO/SparseCore/Dma/HbmMux are NOT wrapped.
    tp = TracePoints<TraceEntry>()            // std::vector<int32> on the stack
    buf = _Znwm(4 * n)                        // {ptr@+0x0, size@+0x8, cap@+0x10}
    write_ids(buf, id_set, n)                 // movl/movabs/vmovaps id stores
    tp.size = n                               // movq $n, slot+0x8
    CoreDispatcher::RegisterSubscriber(dispatcher, tp, sub)  // @0xf1ecee0
    free(buf)                                 // tp freed after each call

RegisterSubscriber 遍历 TracePoints 集中的每个 id,并把 sub 追加到 FlatHashMap[id]。这使注册表成为一个multimap:用重叠 id-set 注册两个 subscriber,意味着单个线上 id 会解析为一个 subscriber 向量,并且 drain 时其中每一个都会运行。

QUIRK — id-set 不是 codec 的属性。codec 知道如何把 id 85 解码成一个 TraceEntry;它不知道在 deepsea gen 上 id 85 必须驱动四个不同 consumer。decode 命名空间(111 项)和路由(少量 id 上的 8..19 个 subscriber)是两个独立结构,只在这里连接。若重新实现时从 decode 表构建路由,并假设“一个 decoder,一个 consumer”,则对每个扇出 id 都是错误的。

id 写入编码

内联的 TracePoints int32 缓冲区使用三种 x86 惯用写法之一填充,取决于集合大小。读回这些写入就是下方每个 id-set 被逐字节精确恢复的方法:

集合大小编码示例
1movl $id,(buf)movl $0x54,… → {84}(pxc reg3, @0xf1ec331
2movabs $0xHI00000000LO,%rcx; mov %rcx,(buf)movabs $0x5a00000059 → {89,90}(@0xf1ec0be
4vmovaps rodata,%xmm0; vmovups %xmm0,(buf)@0xa2d6b40 → {81,82,88,87}(pxc sync)
>4一个 4-id vmovaps base + 按 id 的 movl $id,off(newbuf) 增长复制SC-Syncs {111..116},大小 6(movq $0x6 @0xf22af00

4-id sync vector 位于 .rodata @0xa2d6b40,解码为 {81,82,88,87};其余两个 sync id {86,80} 通过 movabs $0x5000000056 追加。SpiSampler 对 {168,169}movabs $0xa9000000a8

分发(drain)路径

drain 时,CoreDispatcher::Dispatch @0xf1ed280movzwl 0x18(%rax),%edx @0xf1ed2c4 读取线上 id,探测 FlatHashMap,并对每个已注册 subscriber 在 @0xf1ed422/43c/498/4de 调用 *0x10(vtable)(subscriber 的 ProcessTraceEntry)。miss,即某个 id 未注册 subscriber,是未绑定 band 的去向。


Sync / Fence Band(base 80)

用途

TensorCore sync-flag 和 scalar-fence band:80..90 id 范围承载每个 sync-flag update/read/wait 和 scalar-fence start/end。这是唯一带有函数体内字面选择 mask0x1c7)的 band,也是唯一一个直接在这里解码配对语义(wait BEGIN → wait END)的 band。

注册表

id事件名(codec)subscribertracker / 键
80TCS_EXTERNAL_SYNC_FLAG_UPDATE_DMA_DONESyncSubscriberSyncTracker(END, DMA-done)
81TCS_INTERNAL_SET_SYNC_FLAGSyncSubscriber(instant)
82TCS_INTERNAL_ADD_SYNC_FLAGSyncSubscriber(instant)
84TCS_INTERNAL_SET_TRACEMARKTensorCoreStepSubscriberStepTracker(TraceMark id)
85TCS_INTERNAL_TRACE_INSTRUCTIONHlo + Overlay + OnDeviceTraceMe + LloOpOverlayTracker(overlay_id)
86TCS_INTERNAL_UNSUCCESSFUL_SYNC_ATTEMPTSyncSubscriberSyncTracker(wait BEGIN)
87TCS_INTERNAL_SUCCESSFUL_SYNC_ATTEMPTSyncSubscriber(instant — pxc 中不与 tracker 配对)
88TCS_INTERNAL_READ_SYNC_FLAGSyncSubscriber(instant)
89TCS_INTERNAL_SCALAR_FENCE_STARTScalarFenceSubscriber ×2fence span(lines 9 + 62)
90TCS_INTERNAL_SCALAR_FENCE_ENDScalarFenceSubscriber ×2fence span

该邻域还存在两个 codec 名称,但没有被任何 deepsea lambda subscriber 绑定:TCS_INTERNAL_CORE_INTERRUPTTCS_INTERNAL_HOST_INTERRUPT(decode 名称已在 .rodata 中确认;路由未安装 — (unbound, HIGH))。

0x1c7 选择 mask

SyncSubscriber::ProcessTraceEntry(pxc @0xf1eeee0)加载 mov $0x1c7,%esi @0xf1eef3d,并用它测试 (1 << (id - 80))。band base 是 80,因此:

text
0x1c7 = 0b1_1100_0111 = bits {0,1,2,6,7,8} = ids {80,81,82,86,87,88}

这是规范的 band-base 编码:sync trace_point_id 的“selection-mask bit”为 (1 << (id - 80))。它排除 84(tracemark → StepTracker)、85(trace-instruction → 4 路扇出)和 89/90(scalar fence → ScalarFence),这些都由各自注册的 subscriber 路由。

GOTCHA — 0x1c7 mask 是 FlatHashMap 路由的补充,不是替代。SyncSubscriber 注册在 {80,81,82,86,87,88}(mask 集)上,分发已经过滤到这些 id;函数体内 mask 是第二道看似冗余的过滤。只确认 Sync 带有这种函数体内字面 mask。其他所有 subscriber 都纯粹由其注册集合路由;FlatHashMap 是权威选择结构。不要假设其他 band 存在隐藏 bitmask(LOW 置信度:它们有)。


SparseCore Band(base 109)

用途

SparseCore instruction/task/sync band:id 109..120 承载 SC tracemark、trace-instruction、sfence/sync/barrier start-stop 对,以及 task issue→commit span。存在于 gfc/glc/vfc;不存在于 pxc 和 vlc。

NOTE — subscriber 绑定的 SC id 是 109..120,但完整 SC codec band 从更低的 id 108 开始(ScInstructionCoreInterrupt,未绑定 — 没有 deepsea lambda subscriber 路由它),并延伸到 id 132/133 以及 gfc-only PMU samples 134/135。这里的“Base 109”是最低的已路由 id,而不是 band floor;完整的线上 SC 子范围 108..133/135(以及位于其中的 SC-issued OCI 事件 124..130)归 payload-sc-band.md 所有。

注册表

id事件名(codec)subscribertracker / 键
109ScInstructionSetTracemarkSC-Hlo + SC-Task + SC-StepStepTracker(SC TraceMark)
110ScInstructionTraceInstructionSC-Hlo + SC-Task + SC-Overlay + SC-OnDeviceTraceMeOverlayTracker(SC overlay_id)
111ScInstructionSfenceStartSparseCoreSyncsSubscribersfence span
112ScInstructionSfenceStopSparseCoreSyncsSubscribersfence span
113ScInstructionSyncStartSparseCoreSyncsSubscribersync span
114ScInstructionSyncStopSparseCoreSyncsSubscribersync span
115ScInstructionBarrierStartSparseCoreSyncsSubscriberbarrier span
116ScInstructionBarrierStopSparseCoreSyncsSubscriberbarrier span
119ScTaskIssueFromScsSC-Hlo + SC-TaskTaskTracker(task tag, ISSUE)
120ScTaskCommitOnSctSC-Hlo + SC-TaskTaskTracker(task tag, COMMIT)

相邻但未被 SC lambda subscriber 绑定的 codec 名称:ScInstructionSyncWatchStart / ScInstructionSyncWatchStopScInstructionCoreInterrupt(decode 名称存在;(unbound, HIGH))。SC-Syncs subscriber 的 id-set 写作 movabs $0x7200000071 {113,114},随后增长 +0x73{115}+0x74{116}+0x6f{111}+0x70{112},大小 6(movq $0x6,-0x110 @0xf22af00)。

Subscriber 名单(gfc/glc/vfc)

#subscriberTracePoints 集XLine角色
5SparseCoreHloSubscriber{109,110,119,120}SC XLA-op 名称
6SparseCoreTaskSubscriber{109,110,119,120}→ TaskTracker
7SparseCoreOverlaySubscriber{110}142 SC Overlay→ OverlayTracker
8SparseCoreOnDeviceTraceMeSubscriber{110}100 SC TraceMeTraceMe span
9SparseCoreStepSubscriber{109}117 SC Steps→ StepTracker
10SparseCoreSyncsSubscriber{111,112,113,114,115,116}67 SC Syncssfence/sync/barrier

QUIRK — id 109 和 110 各自扇出到不同的 subscriber 集。109(tracemark)命中 Hlo+Task+Step;110(trace-instruction)命中 Hlo+Task+Overlay+TraceMe。Task subscriber 监听完整 {109,110,119,120},但只有 119/120 对实际配成 span;109/110 为完整性而到达它。这是 TensorCore 85 扇出的 SC 对应物。


OCI / ICI / UHI Bands(互连)

用途

片上(OCI)、片间(ICI)和 host-bridge(UHI)互连 band。它们承载线上事件量的大部分:跨引擎的 message issue/receive、ICI link packet 流,以及 UHI host-bridge 流量;但在 deepsea CoreContext lambda 中没有专用语义 subscriber

注册表(代表性 — OCI message 事件)

OCI band 的 decode 名称形成 20 事件的 OciMessage* family,命名片上 message 的每一跳:

事件名(codec)含义
OciMessageIssuedFromTcs从 TensorCore sequencer 发出的 message
OciMessageIssuedFromMgr从 MGR firmware 发出的 message
OciMessageMsgIssuedFromEngine / ...FromQnmengine / QNM 发出
OciMessageSentByBc / ...BySc / ...ByCmnde / ...ByHde按 source block 的 egress
OciMessageSentByUhiBridge / OciMessageReceivedByUhiBridgeUHI band — host-bridge hop
OciMessageReceivedByBc / ...BySc / ...ByMgr按 dest block 的 ingress
OciMessageGeneratedInIcrEgressDma / ...IngressDmaICR DMA-bridge 生成
OciMessagePacketReceivedInIcr / OciMessagePacketSentToOciOCI/ICR 边界
OciMessageSyncFlagUpdateFromDstEngine经 OCI 携带的 sync-flag update

ICI link flow 使用并行的 IciPacket* decode family:IciPacketControlPacketInjectedByIcrDmaBridge / ...QueuedForLocalIngress / ...ReceivedByIcrDmaBridge,匹配的 IciPacketDataPacket* 三元组,以及 link 侧的 IciPacketPacketQueuedForLinkTransmission / ...ReceivedOnLinkInput / ...TransmittedOnLinkOutput

UHI band 不是独立 id 范围,而是 OCI/ICR 事件中命名 UHI host bridge(*UhiBridge)的子集。UhiBridge 符号存在;UHI 事件搭载在 OCI codec 上。

NOTE — OCI/ICI/UHI band 的逐 id 数值归 codec decode table 所有(有空洞的 0..255 跳转表索引)。本页声明名称band 成员关系,两者都已从 .rodata 逐字节确认;互连 band 的精确 id→name 数值配对作为跳转表索引位于 codec 页面。

未绑定 band — deepsea 上的 UHI/OCI/ICI/DMA

CoreContext lambda 只注册约 8..19 个语义 subscriber(Sync/Step/Hlo/Overlay/TraceMe/Llo/ScalarFence/SparseCore*/Firmware/Throttle/Spi)。占主导的互连和 DMA band 在 FlatHashMap 中没有条目,因此在 deepsea gens 上它们会落到 raw TraceEventSubscriber 路径:事件名变为 id 的 FastIntToBuffer 十进制字符串,并作为通用 XEvent 发出,或者该 id 被丢弃。具体是哪一种,以及 deepsea gens 上是否注册了单独的 DmaSubscriber(它只在 jxc 上存在),未解决 (LOW)。这是主注册表中最大的完整性缺口:线上流量最多的 band,语义绑定最少。


DMA Band

用途

DMA started/completed band:CMQ/CMN/HDE descriptor request + data-end 事件,按 dma_id 配对。在 jxc 上它是一等 DmaSubscriber;在 deepsea 上它未绑定(见上)。

注册表

元素
request decode 名称CmnDmaRequestEastSideLane / ...WestSideLane / CmnDmaRequestSet
DMA 引擎CMQ(queue)、CMN/CMNDE(notify)、HDE(host)
配对键dma_id = GetDmaId() — first descriptor = BEGIN,data-end = END
jxc subscriberDmaSubscriber — 基于 MemoryCommand()/GetDmaId() 路由,不是静态 id-set
jxc HBM muxHbmMuxSubscriber — HBM-mux band,基于 MemoryCommand 路由

GOTCHA — jxc DmaSubscriberHbmMuxSubscriber 完全不注册 TracePoints int32 集。它们基于已解码的 MemoryCommand() accessor 动态路由,而不是基于线上 trace_point_id。如果重新实现时预期每个 subscriber 都带有 id-set,就会错误建模这两个;它们是注册机制的例外。


Throttle Band(base 104 / 200)

用途

电源管理 cycle-skip band:throttle 事件由 RunLengthTracker<unsigned int> 按键处理,把连续 cycle-skip sample 合并成 run。band base 依 gen 而定:vfc/vlc 上是 104,gfc/glc 上是 200

注册表

id事件subscriber
104ThrottleCycleSkip band base(vfc/vlc)PowerThrottleSubscriber
200ThrottleCycleSkip band base(gfc/glc)PowerThrottleSubscriber

deepsea throttle decode 名称按 brake 来源形成很深的 ThrottleCycleSkip* 分类:...ElectricalBrakeEventCycleSkipLdidtBrake...ElectricalDroopEvent...LdidtDroop...ExternalBrakeEvent...ExtBrake...ExternalThrottleEvent...ExtThrottle,以及 PPM family(...PpmBrakeEventDidtAggressive/Nominal...OvershootAggressive/Nominal...SustainedAggressive/Nominal,再加 rising/falling-edge 变体)。RunLengthTracker 的逐 sample 累积键(每个 run 目标是哪条 thermal/power counter line)解码 (LOW)。vfc base 写作 movl $0x68 = 104 @0xf2027ae;gfc 为 movl $0xc8 = 200 @0xf229cee


MGR / Power Band(base 160)

用途

MGR firmware power/p-state band:base 160 加 168/169 SPI sampler 对。这些 subscriber 包装 RunLengthTracker<double>(firmware)/ <...EventBuilder>(SPI)累加器,而不是配对 begin/end span。

注册表

id事件subscriber
160MgrFwEvent / MGR band basePStateTrackerSubscriber + FirmwareSubscriber(gfc/glc 上还有第 2 个 component FW)
168SPI sampler(gfc/glc)SpiSamplerSubscriber
169SPI sampler(gfc/glc)SpiSamplerSubscriber

第 2 个 FirmwareSubscriber(仅 gfc/glc)包装 RunLengthTracker<FirmwareComponentEventBuilder>,并发出逐 component power line(kComponents 120..130 / 134..138)。SpiSamplerSubscriberSpiSamplerSubscriber / PowerSpiSamplerEventBuilder 已确认)包装 RunLengthTracker<PowerSpiSamplerEventBuilder>,lines 118/119,id-set {168,169}movabs $0xa9000000a8 @0xf22c3aa)。vfc/vlc 既没有第 2 个 Firmware,也没有 SPI sampler。MGR base 是 movl $0xa0 = 160


pxc(BarnaCore)Gen

用途

pxc(pufferfish)是 BarnaCore gen,即最简单的 deepsea family,8 个 subscriber没有 SparseCore band,也没有 power/throttle subscriber。它的高 id 空间只包含 TC sync/fence/instruction band。

注册表

#subscriberTracePointsXLinetracker/key
1SyncSubscriber(threaded){80,81,82,86,87,88} mask 0x1c717sync_flag_number
2ScalarFenceSubscriber(threaded){89,90}9 Scalar Unitfence span
3TensorCoreStepSubscriber(threaded){84}1 StepsTraceMark id
4TensorCoreHloSubscriber{85}3 XLA Ops(HLO name)
5TensorCoreOverlaySubscriber(threaded){85}7 TC Overlayoverlay_id
6TensorCoreOnDeviceTraceMeSubscriber{85}6 XLA TraceMeTraceMe span
7LloOpEventSubscriber(threaded){85}8 Tensor Core(LLO op)
8ScalarFenceSubscriber(threaded){89,90}62 Barna Core Fencefence span

id 85(TCS_INTERNAL_TRACE_INSTRUCTION)的 4 路扇出在这里最清楚:subscriber 4/5/6/7 都注册 {85}。它们共享的 -0xc0 {85} 栈缓冲区只分配一次、释放一次(@0xf1ecafb)。subscriber 2 和 8 都是在 {89,90} 上的 ScalarFenceSubscriber,但发到不同设备 line(9 Scalar Unit 与 62 Barna Core Fence),由 +0x18 line 字段区分(movl $0x9,0x18 vs movl $0x3e,0x18 = 62)。


jxc(jellyfish)Legacy Gen

用途

jxc(jellyfish)是旧式 PerformanceTraceEntry gen,是唯一使用旧 codec 的 family,具有不同于 deepsea 0..255 band 的 16 位 id 命名空间,也是唯一带有 HbmMux + Dma subscriber 的 gen。10 个 subscriber(lambda @0xf1da7c0)。

注册表(jellyfish 16 位 id)

#subscriberTracePoints(jellyfish ids)
1HbmMuxSubscriber(threaded)(HBM-mux band;基于 MemoryCommand 路由)
2DmaSubscriber(基于 MemoryCommand()/GetDmaId() 路由)
3SyncSubscriber(threaded){0xa3d,0xa3e,0xa42,0xa43,0xa44,0x93c}
4ScalarFenceSubscriber(threaded){0xa45,0xa46} = {2629,2630}
5TensorCoreStepSubscriber(threaded)(TC SetTracemark,jellyfish id)
6TensorCoreHloSubscriber(TC TraceInstruction,jellyfish id)
7TensorCoreOverlaySubscriber(threaded)(same)
8TensorCoreOnDeviceTraceMeSubscriber(same)
9LloOpEventSubscriber(threaded)(same)
10ScalarFenceSubscriber(threaded){0xa45,0xa46}

sync id-set 打包为 movabs $0xa430a440a3e0a3d @0xf1db880(16 位半字 0xa3d/0xa3e/0xa44/0xa43)+ movl $0x93c0a42{0xa42,0x93c})。ScalarFence 集是 movl $0xa460a45{0xa45,0xa46})。TC 单 id 集(subscriber 5..9)和 HbmMux band 逐项枚举 (LOW);jellyfish-id → event-name cross-walk 归 jxc legacy payload page 所有。jellyfish::TraceOperandPerformanceTraceEntry 符号已确认存在。

QUIRK — jxc subscriber 3/4/10 复用与 deepsea gens 相同的 C++ subscriber 类型(SyncSubscriber、ScalarFenceSubscriber),但喂给它们的是完全不同命名空间中的 id。subscriber 类型可移植;id-set 不可移植。按 deepsea band base(80/109/160)索引的跨 gen 路由表会静默误路由每个 jxc 事件;唯一共同点是 subscriber 分类,不是 id。


五个有状态 Tracker — 匹配键

tracker 是 subscriber 之上的 begin/end 配对层。每个 tracker 消费固定 id 子集,并在一个字段上配对 span;这是 SyncTracker(sync_flag_number)DmaSubscriber(dma_id) 的类似层。

tracker输入(trace_point_ids)begin 事件end 事件MATCH KEY
SyncTracker80,86(+81,82,87,88 instant)86 UNSUCCESSFUL_SYNC(ProcessSyncBlock80 DMA_DONE(ProcessSyncUnblocksync_flag_number
DmaSubscriberCMQ/CMN/HDE req + data-endFirst()/MemoryCommandLast()/MemoryDataEnddma_id = GetDmaId()
StepTracker84(TC)/ 109(SC)TraceMark 0x7fffffffTraceMark 0x7ffffffeTraceMark id(state+0x8)
TaskTracker119,120(仅 SC)119 ScTaskIssueFromScs120 ScTaskCommitOnScttask tag(FlatHashMap)
OverlayTracker85(TC)/ 110(SC)operand kind 0xd(open)operand kind 0x9(close)overlay_id(state+0x8)

StepTracker — TraceMark id,sentinel 区分

StepTracker::ProcessTraceEntry<gfc> @0xf231900 读取 id 并按 core type 分发:TC(id 0x54=84,marker 来自 TcsInternalSetTracemark_globals_+0x18)或 SC(id 0x6d=109,来自 ScInstructionSetTracemark_globals_+0x18)。它构建 TraceMarkEntry{+0x0 step_id, +0x8 mark_type, +0x10 gtc, +0x18 flag},并调用共享的 StepTracker::ProcessTraceEntry @0xf2c4480。Mark-type sentinel(cmp @0xf2c44bd/4f1/4513/4580/4589):

text
0x7fffffff  step-BEGIN marker  → close any open step, open a new one keyed by the marker id
0x7ffffffe  step-END marker     → close the open step, emit StepInfo{step_id, start, end}
0x7ffffff9  intra-step marker   → annotate the open step without closing it

状态结构:+0x8 = 当前 step id(匹配键),+0x10 = start gtc,+0x28 = flag,+0x30 = present。

TaskTracker — task tag,FlatHashMap keyed

TaskTracker::ProcessTraceEntry<gfc> @0xf2394e0。id 0x77=119(ScTaskIssueFromScs,oneof 0x4d)从 ScTaskIssueFromScs_globals_+0x28 读取 tag,并在 FlatHashMap<tag, pending> 中记录 pending task(probe mulq 0x28(%r12),cap cmp 0x38(%r12))。id 0x78=120(ScTaskCommitOnSct,oneof 0x4e)从 +0x20 读取匹配 tag,查找它,并在匹配时通过 ProcessTaskCommit @0xf2c4ce0 发出 TaskInfo{+0x8 tag, +0x50 present}。Begin = 119,end = 120,key = task tag。仅 SparseCore。

OverlayTracker — overlay_id operand

OverlayTracker::ProcessTraceEntry<gfc> @0xf2335c0 按 core-type selector(state+0x0:2=TC,5=SC)分发,过滤 id + block_id+0x1c 对 state+0x4),并提取 operand:TC id 0x55=85(operand 来自 TcsInternalTraceInstruction_globals_+0x18)/ SC id 0x6e=110(来自 ScInstructionTraceInstruction_globals_+0x18)。OverlayTracker::ProcessTraceOperand @0xf2c3e40 按 operand kind 分支:

text
0xd  overlay OPEN   → record overlay_id at state+0x8 (match key), active flag +0xc, start gtc +0x10
0x9  overlay CLOSE  → emit OverlayInfo{overlay_id, start, end=gtc}, clear +0x8/+0x10

两者都搭载在 id 85(TC)/ 110(SC)上;open/close 判别项是 operand kind,而不是独立 id。


相关结构 / 表偏移

结构布局
TracePoints<TraceEntry>std::vector<int32> {ptr@+0x0, size@+0x8, cap@+0x10};在栈上构建,每次 register 后释放
CoreDispatcher mapFlatHashMap<u16 id (TraceHeader+0x18), vector<shared_ptr<TraceEventSubscriber>>>
TraceEventSubscriber base+0x08/+0x0c core_id/chip_id filter;+0x10 TpuXPlaneBuilder*;+0x18 每 id XEventMetadata* cache / line 字段
ThreadedSubscribervtable + ClosureThread worker(pxc 中 ThreadLoop @0xf1ede60)位于 +0xa0;wrapped vtable 内联设置
StepTracker state+0x8 step id(key),+0x10 start gtc,+0x28 flag,+0x30 present
TaskTracker stateFlatHashMap<tag, pending>TaskInfo{+0x8 tag, +0x50 present}
OverlayTracker state+0x8 overlay_id(key),+0xc active flag,+0x10 start gtc
sync id rodata@0xa2d6b40 = {81,82,88,87};+{86,80} 通过 movabs $0x5000000056

交叉引用