Skip to content

v7x Perf-Counters

本页中的所有地址均适用于来自 libtpu-0.0.40-cp314 wheel 的 libtpu.so(build-id 89edbbe81c5b328a958fe628a9f2207d)。.text.rodata.lrodata section 映射满足 VMA == 文件偏移;kDeviceTypeInfo 位于 VMA 0x1c60480。其他 build 会有所不同。

摘要

TPU profiler 暴露两层不同的设备端 telemetry,它们共享同一个后备结构:kDeviceTypeInfo 数组(17 项,stride 0x448 = 1096 字节,每个 DeviceType 一项)。第一层是具名硬件性能计数器解析器GetPerformanceCounterNames<N>0xf240980 / 0xf240c00 / 0xf240ac0),它把用户选择的 counter ordinal 转成 profiler 标到 counter timeline 上的片上寄存器名称。第二层是 firmware power/thermal/DVFS 事件模型ConvertFirmwareTraceEntriesToXPlane 输入 FirmwareEventBuilder,把 firmware trace 转换为 power、temperature、throttle 和 P-state XStats。两者都从同一条 kDeviceTypeInfo 行读取各代常量。

perf-counter 层最重要的事实是:除一个 silicon generation 外,它在所有 generation 上都是惰性的。三个 resolver 实例化开头都是 if (DeviceType == 12),否则立即返回。DeviceType 12 是 v7x,它是不同于 v6e(DeviceType 13)的独立 silicon generation;这同时由 enum 名称字符串(.rodata 中存在 v7xv6eViperfish)和 descriptor 字节确认:只有 0x1c637e0 行(index 12)带有非零 perf-counter enum base;其他每一行在六个 descriptor 字段上都是全零。因此,“v7x” 不是叠加在旧 silicon 上的 counter-naming 轴,而是此 build 中唯一暴露具名设备端 counter 的 generation。counter-name dispatcher 本身位于 asic_sw::driver::deepsea::gxc::gfc::profiler namespace;gfcgxc namespace profiler codec family 之一(glc 的 sibling),v7x 通过它解析 counter 名称(本页在 § Codec Family 中建立该关系)。

六个 perf-counter set 与六个 STATS_COUNTER_SAMPLE_ISSUED_FROM_{TCS,SCS,SCTC,SCTD,CMNUR,ICR} tracepoint source 1:1 对应:TensorCore Sequencer、SparseCore Scalar、SparseCore Tile Compute、SparseCore Tile DMA、memory-network/HBM controller,以及 ICI router。tracepoint 携带采样到的 counter ;此 resolver 提供它们的名称。本页涵盖:resolver 及其 base + index*8 enum 编码;六个 kDeviceTypeInfo descriptor 字段和恢复出的 counter-name 字符串;请求驱动的 counter-index 选择(GetTpuCounterIndicesFromRequest);以及 firmware FirmwareEventBuilder 事件模型和它的各代 calibration bundle。

对于重新实现,契约是:

  • DeviceType == 12 gate,以及每个 resolver 使用的 PerformanceCounterName = base + ordinal*8 enum 编码。
  • 六个 kDeviceTypeInfo descriptor 字段(+0x2c8/+0x348/+0x350/+0x358/+0x438/+0x440)是打包的 enum base(不是 bit-mask),每个 counter set 一个,并带有 resolver inline-cap(28/28/28/28/3/12)。
  • GetTpuCounterIndicesFromRequest 中的 request→set 连接:哪个 XprofRequest flag bit 选择哪个 TpuCounterIndices member,并输入哪个 resolver。
  • firmware 事件模型:五个 TraceEntry oneof 变体、RunLengthTracker 聚合、power/temperature/throttle/P-state 公式,以及各代 +0x360..+0x398 calibration bundle。
Resolver <28>xprof::tpu::GetPerformanceCounterNames<28> @ 0xf240980
Resolver <12>...<12> @ 0xf240c00(ICR set)
Resolver <3>...<3> @ 0xf240ac0(CMNUR/HBM set)
名称 dispatcherasic_sw::driver::deepsea::gxc::gfc::profiler::PerformanceCounterNameToString @ 0x1fc701e0(20 个 band 子 decoder 0x1fc703e0..)
请求 decoderxprof::tpu::GetTpuCounterIndicesFromRequest @ 0xf2c5000
调用方ConvertTpuTraceToXPlaneV2<...jxc::PerformanceTraceEntry>(六个 call site)
Firmware convertConvertFirmwareTraceEntriesToXPlane<...gfc::TraceEntry> @ 0xf2b1ee0(vlc 0xf27f140,glc 0xf29d5c0,vfc 0xf28ae00
Firmware builder ctorFirmwareEventBuilder<...gfc::TraceEntry>::FirmwareEventBuilder @ 0xf2b8780(vlc 0xf284d20
kDeviceTypeInfo0x1c60480,17 × 0x448;v7x 行(DT12)@ 0x1c637e0
活跃 generationDeviceType == 12 = 仅 v7x;其他所有行全零

v7x Gate 与 Counter-Name Resolver

用途

GetPerformanceCounterNames<N> 是命名设备端 HW performance counter 的函数。给定用户选择的 counter ordinal 列表和一个按 set 的 enum base,它会为每个 ordinal 生成一个 string_view 名称。这些名称成为 v7x counter timeline 上的列标签。它有三个实例化,区别仅在 InlinedVector inline capacity N,即该 set 可承载的最大 counter 数:<28> 用于四个 TensorCore/SparseCore set,<12> 用于 ICI router set,<3> 用于 HBM/memory-network set。

入口点

text
ConvertTpuTraceToXPlaneV2<jxc::PerformanceTraceEntry>      ── six call sites, one per counter set
  └─ GetPerformanceCounterNames<28|12|3> (0xf240980 / 0xf240c00 / 0xf240ac0)
       └─ gxc::gfc::profiler::PerformanceCounterNameToString (0x1fc701e0)
            └─ ToString0..19 (0x1fc703e0 ..)   ── 20 banded binary-search sub-decoders

算法

三个 resolver 共享同一函数体。这里复现 <28> 形式;<12><3> 只在 inline-capacity 常量上不同。

c
function GetPerformanceCounterNames_28(DeviceType d,        // 0xf240980
                                       const int* idxs, size_t n,
                                       uint64_t base,        // the kDeviceTypeInfo field
                                       InlinedVector<string_view,28>* out):
    if d != 12:                       // 0xf240980 — gate: ONLY v7x; every other gen returns empty
        return
    reserve(out, n)                   // grow inline storage if n > current cap
    for i in 0 .. n-1:                // loop @ 0xf240a20
        ordinal = idxs[i]             // movsxd from the request-selected index vector
        name = PerformanceCounterNameToString(base + 8 * ordinal)   // 0xf240a28
        out.push_back(name)           // EmplaceBackSlow when storage is full

算术 base + 8*ordinal 就是完整编码(call site 0xf240a24 处的 lea rdi,[r14 + rax*8],其中 r14 持有按 set 的 base)。PerformanceCounterName 是打包的 32 位 enum;按 set 的 base 选择 counter family(chiplet / unit / domain),ordinal 则以 8 为缩放索引其中的 counter。

QUIRK — <N> template 参数是 InlinedVector inline capacity,即按 set 的最大 counter 数;不是 counter ID,也不是 device generation。<28> 承载最多 28 个名称,<12> 最多 12 个,<3> 最多 3 个。把 N 当成其他含义的重新实现会错误设置四个 SparseCore/TensorCore set 的大小。

GOTCHA — DeviceType == 12 gate 是完整的 generation guard。没有 fallback 路径:在 v6e、v5p、v5e、v4、v3、v2 上,resolver 返回空 vector,counter timeline 不带名称。若重新实现省略该 gate,或在非 v7x kDeviceTypeInfo 行(base 为零)上驱动 resolver,就会解引用 PerformanceCounterNameToString(0 + 8*ordinal),并生成垃圾 / 空字符串,而不是预期的 no-op。

六个 Descriptor 字段

六个 kDeviceTypeInfo 尾部字段是打包的 32 位 PerformanceCounterName enum base,每个 counter set 一个。它们存储在低 32 位,高 32 位为零;在 v7x(DT12,行 0x1c637e0)上逐字节精确读出为:

kDTI 字段ResolverInline cap子系统(STATS_COUNTER source)v7x base
+0x2c8<28>28TCS — TensorCore Sequencer0xa668a008
+0x348<28>28SCS — SparseCore Scalar0xa7f61008
+0x350<28>28SCTC — SparseCore Tile Compute0xa7724008
+0x358<28>28SCTD — SparseCore Tile DMA / TEC0xa6726008
+0x440<3>3CMNUR — memory-network / HBM controller0xa5463408
+0x438<12>12ICR — ICI router(data)0xd6438c08

NOTE — 这六个字段不是 bit-mask。每个字段都是打包的 PerformanceCounterName enum base,会与 ordinal*8 相加。resolver 函数体中的 base + ordinal*8 算术(lea rdi,[r14+rax*8])直接证明该字段是加法 base,不是 mask。共有六个 counter set,包括 +0x440<3> CMNUR 和 +0x438<12> ICR。

其他每个 DeviceType 行在这六个字段上都是 0x00000000;扫描全部 17 行验证只有 index 12(0x1c637e0)非零。因此,整个具名 counter 机制在此 build 中是 v7x 专属的。

恢复出的 Counter 名称

实际 counter 字符串位于通过 20 个 band 子 decoder 到达的 gfc 名称表(SamplingData::kNames / kOffsets)中。对每个 set 的前几个 ordinal 解析 base + ordinal*8,可逐字节精确恢复名称(全部确认存在于 .rodata);完整寄存器前缀是 v7x 复用的 VF_(Viperfish-register)namespace:

Setbaseordinal 0..3(..._UNPRIVILEGED_ 之后的 suffix)
SCS(+0x3480xa7f61008COUNT_CYCLES / COUNT_SCALAR_ISSUE / COUNT_BRANCH_TAKEN / COUNT_S0_INSTRUCTION
SCTC(+0x3500xa7724008COUNT_CYCLES / COUNT_VECTOR_ISSUE / COUNT_V0_INSTRUCTION / COUNT_V1_INSTRUCTION
SCTD(+0x3580xa6726008COUNT_CYCLES / TEC_SCALAR_ISSUE / TEC_BRANCH_TAKEN / TEC_S0_INSTRUCTION
CMNUR(+0x4400xa5463408CYCLE_COUNTER_WINDOW / RD_RSP_BEAT_FROM_HBM / WR_REQ_BEAT_TO_HBM
ICR(+0x4380xd6438c08LINK0_EGRESS_CONTROL_PACKET_SENT / LINK0_EGRESS_DATA_PACKET_SENT / LINK0_INGRESS_CONTROL_PACKET_RECEIVED / LINK0_INGRESS_DATA_PACKET_RECEIVED
TCS(+0x2c80xa668a008(未命名 — 见 GOTCHA)

示例完整名称(已在二进制中逐字确认):

text
VF_CHIP_DIE0_SC_0_SCS_SC_STATS_COUNTERS_UNPRIVILEGED_COUNT_CYCLES
VF_CHIP_DIE0_CMN_CMNUR_0_CMN_STATS_DEBUG_FIXED_STATS_COUNTERS_UNPRIVILEGED_RD_RSP_BEAT_FROM_HBM
VF_CHIP_CHIPLET_ICR_ICR_DATA_0_DEBUG_DOMAIN_ICR_DATA_STATS_PACKET_COUNTERS_UNPRIVILEGED_LINK0_EGRESS_DATA_PACKET_SENT

GOTCHA — +0x2c8 处的 TCS(TensorCore)set 经 PerformanceCounterNameToString 解析到一个 gfc dispatcher 不映射的 enum band;ordinal 0..N 在那里返回空。该 set 确实是 TCS source(与 STATS_COUNTER_SAMPLE_ISSUED_FROM_TCS0x10000000 request flag 1:1 对应),并使用 <28> resolver,但 TensorCore counter 字符串位于 decoded here 的 gfc band chain 未到达的独立 TC-specific name table 中。重新实现者必须定位该 TC table,才能命名 v7x TensorCore counter;其他五个 set 是完整的。

Codec Family(gfc)与 v7x Gate {#codec-family-gfc-vs-the-v7x-gate}

名称 dispatcher 是 asic_sw::driver::deepsea::gxc::gfc::profiler::PerformanceCounterNameToStringgfcgxc namespace 中的 profiler codec family(与 glc 同为 sibling;vlc/vfc 位于 vxc 下)。resolver gate 是 DeviceType == 12 = v7x,但通过 gfc 表解析名称。这是一致的,并不矛盾:v7x 是比 v6e(DeviceType 13)更新的 silicon generation,但它共享 gfc profiler codec 和 Viperfish(VF_)寄存器 namespace。firmware 路径作出相同选择:FirmwareEventBuilderConvertFirmwareTraceEntriesToXPlane 实例化在 gfc::profiler::TraceEntry codec 上(并列存在 vlcglcvfc sibling)。因此 v7x/gfc 的关系是:v7x 是由 gfc codec 服务的一个独立 DeviceType,enum base 和 calibration 常量按 kDeviceTypeInfo 行变化。


请求驱动的 Counter 选择

用途

交给 resolver 的 counter-index vector 不是硬编码在二进制中的,而是由 profiling request 通过用户选择。GetTpuCounterIndicesFromRequest0xf2c5000)把 XprofRequest.PeriodicCounterSamplingOptions repeated-int proto 字段复制到一个 TpuCounterIndices struct 的六个 InlinedVector<int,N> member 中,由五个 flag bit 加一个 byte flag 控制。

算法

c
function GetTpuCounterIndicesFromRequest(XprofRequest* req,        // 0xf2c5000
                                         TpuCounterIndices* out):
    flags = req->u32[+0x10]
    if flags & 0x10000000:  Assign<28>(out + 0x000, req->sampling_opts[+0xb8])   // TCS
    if flags & 0x20000000:  Assign<28>(out + 0x078, req->sampling_opts[+0xc0])   // SCS
    if flags & 0x40000000:  Assign<28>(out + 0x0f0, req->sampling_opts[+0xc8])   // SCTC
    if flags & 0x00000020:  Assign<28>(out + 0x168, req->sampling_opts[+0x48])   // SCTD
    if (int)flags < 0:      Assign<3> (out + 0x1e0, req->sampling_opts[+0xd0])    // CMNUR (sign bit = 0x80000000)
    if req->u8[+0x14] & 1:  Assign<12>(out + 0x1f8, req->sampling_opts[+0xd8])    // ICR

Assign<N>absl::inlined_vector_internal::Storage<int,N>::Assign<...>,它把 repeated-int proto 字段(一个 RepeatedIterator<int const> range)复制到 member 的 inline storage 中。每个 member 的 <N> 与 resolver cap 完全匹配:四个 SparseCore/TensorCore member 是 28/28/28/28,CMNUR 是 3,ICR 是 12。

Request → Set 连接

Flag bitTpuCounterIndices memberAssign<N>输入的 ResolverkDTI baseSet
+0x10 & 0x10000000+0x000<28><28>+0x2c8TCS
+0x10 & 0x20000000+0x078<28><28>+0x348SCS
+0x10 & 0x40000000+0x0f0<28><28>+0x350SCTC
+0x10 & 0x00000020+0x168<28><28>+0x358SCTD
+0x10 & 0x80000000(sign)+0x1e0<3><3>+0x440CMNUR
+0x14 & 0x1+0x1f8<12><12>+0x438ICR

NOTE — 第一个 member 位于 struct offset +0x000,不是 +0x8。反编译出的 Assign target 是裸 struct pointer,因此六个 member 位于 0x000 / 0x078 / 0x0f0 / 0x168 / 0x1e0 / 0x1f8。下游调用方(ConvertTpuTraceToXPlaneV2)从这些 offset 读取每个 InlinedVector.data(),并在调用 resolver 前把它与匹配的 kDTI base 配对。

随后,六个填充后的 vector 会在 ConvertTpuTraceToXPlaneV2 中逐一交给六次 GetPerformanceCounterNames 调用。因而 request flag 决定收集哪些 counter;resolver 决定它们叫什么


Firmware Telemetry 事件模型

用途

ConvertFirmwareTraceEntriesToXPlane<fam> 把 firmware trace 转换为 power / temperature / throttle / P-state 事件。它从 kDeviceTypeInfo 行加载按 generation 的 calibration bundle,构造 FirmwareEventBuilder<fam>,对 trace 做 run-length 聚合,并写回 DVFS P-state timeline。它按 codec family 实例化:gfc0xf2b1ee0)、vlc0xf27f140)、glc0xf29d5c0)、vfc0xf28ae00),形状相同。

入口点

text
ConvertFirmwareTraceEntriesToXPlane<gfc::TraceEntry> (0xf2b1ee0)
  ├─ load [kDTI + DeviceType*0x448 + 0x360..+0x378]  ── 4 doubles  (power/thermal calibration)
  ├─ load [kDTI + DeviceType*0x448 + 0x380..+0x398]  ── 4 ulongs   (meter / sensor / window counts)
  ├─ FirmwareEventBuilder<gfc>::ctor (0xf2b8780)      ── caches 19 XLines + 5 XStatMetadata
  ├─ RunLengthTracker<double,...>::ProcessTraceEntry  ── per entry: Get() value, close runs on change
  ├─ FirmwareEventBuilder::Flush                       ── close the trailing run
  └─ assign vector<pair<u64, PState>>& (out arg)       ── the DVFS timeline

算法

c
function ConvertFirmwareTraceEntriesToXPlane_gfc(entries, gtc_span,    // 0xf2b1ee0
                                                 DeviceType d,
                                                 vector<pair<u64,PState>>& dvfs_out,
                                                 TpuXPlaneBuilder* xb):
    if d >= 17: trap                          // 0x448-stride bound check
    row = kDeviceTypeInfo + 1096 * d          // 1096 == 0x448
    doubles = { row[+0x360], row[+0x368], row[+0x370], row[+0x378] }   // bias/scale pair per rail
    ulongs  = { row[+0x380], row[+0x388], row[+0x390], row[+0x398] }   // meter/sensor/window counts
    fb = FirmwareEventBuilder_gfc(xb, doubles..., ulongs...)           // 0xf2b8780
    for e in entries:
        RunLengthTracker.ProcessTraceEntry(fb, e)   // Get() -> value; OnEvent() closes prev run
    fb.Flush()
    dvfs_out = fb.dvfs_timeline                       // __assign_with_size of pair<u64,PState> vector

Builder 状态

FirmwareEventBuilder ctor(0xf2b8780)布局为:

obj offset来源含义
+0x00xbTpuXPlaneBuilder*
+0x08 / +0x0cxb[+0x8c] / xb[+0x90]core / chip id
+0x10 / +0x18 / +0x20 / +0x28kDTI +0x360..+0x3784 个 calibration double(bias/scale)
+0x30 / +0x38 / +0x40 / +0x48kDTI +0x380..+0x3984 个 calibration ulong(counts)
+0x60 / +0x581919 项 TpuComponent vector 大小
+0x80"power"(id 5)XStatMetadata
+0x88"temperature"(id 11)XStatMetadata
+0x90"throttle %"(id 10)XStatMetadata
+0x98"P State"(id 7)XStatMetadata
+0xa0"PCIe BW (GB/s)"(id 14)XStatMetadata

19 个 firmware XLine component 从 ymmword_AB59ACC0xab59acc 处的 int32[19])逐字节读取:{120,121,122,123,124,125,126,127,128,129,130,134,135,136,137,138,139,141,143}。按 TpuComponentName,它们是 VDD-core power meters PL1..PL4、VDD-core throttle、HBM power meters PL1..PL4、HBM throttle、HBM max temperature、PCIe read utilization 1..4、PCIe write utilization 1..2、ICR Stats,以及 Compute-Die max temperature;均已作为 .rodata 字符串确认(例如 "VDD Core FW Power Meter PL1(W)""Compute Die FW Max Temperature(C)")。

五个事件 Family

firmware TraceEntry 是 oneof;FirmwareEventBuilder::Get0xf2b8b00)按变体分发,并使用 obj 中存储的 calibration 常量计算每个事件的值:

变体(proto message)Get() 值公式XLine / XStat
PowerLevelEventpower(W) = (raw_energy/Δt − bias) / (meter_count·1000.0),由 obj +0x10/+0x18 缩放并由 +0x20/+0x28 加偏置120..128 / "power";PCIe 134..139 / "PCIe BW (GB/s)"
ThermalEventtemperature(C) = cvtsi2sd(thermal_sensor_int)130/143 / "temperature"
ThrottleEventthrottle% = (throttle_cycles·100.0) / cycle_window124/129 / "throttle %"
DvfsEventP-state = cvttsd2si(dvfs_p_state);push pair<u64 ts, PState>DVFS timeline / "P State"
MgrFwEvent(tag 94)manager-firmware status passthroughmgr line

常量固定在 .rodata 中:qword_A2DF5C0 处的 100.0qword_A2E0430 处的 1000.0qword_A2DF230 处的 1.0,以及 xmmword_A2C1520 / xmmword_A2C5F90 处的 u64→double 2^52 重建 magic。PowerLevel 路径使用 obj +0x10/+0x18 作为按 rail 的 scale,+0x20/+0x28 作为 bias(两个 rail;v35 == 1v35 == 2 分支选择哪个 double 对)。

NOTE — 精确的 power_level_index → power-meter-line 路由(PL1..PL4 中哪个映射到哪个 kDeviceTypeInfo power-meter instance、VDD-core rail 还是 HBM rail)是从 OnEvent component-index 选择中结构化解码出来的,但未逐 index 枚举。19-line 集、5 个 stat 和 power 公式已固定;OnEvent 内每个 power_level_index 的 line assignment 是 firmware 路径中的一个中等置信度缺口。

RunLengthTracker 和 OnEvent

RunLengthTracker<double, FirmwareEventBuilder, ...>::ProcessTraceEntry 是聚合引擎。对每个 trace entry,它调用 Get() 提取当前 scalar;当值变化(run-length 边界)时,它调用 OnEvent(span=[prev_gtc, cur_gtc], prevEntry, curEntry, value),把上一个 run 关闭为单个 duration XEvent,然后记录新 run。Flush 关闭尾部 run。

OnEvent(gfc 中 0xf2b8d20)对每个事件:从变体选择 component index,GetOrCreateLine(TpuComponent)AddEvent(GtcSpan, XEventMetadata),也就是写入通用 device_offset_ps / device_duration_ps stat,然后用匹配的 interned stat("power" / "temperature" / "throttle %",位于 obj +0x80..+0x90)调用 AddStatValue<double&> 加上数值。DvfsEvent 路径把一个 pair<u64 timestamp, PState> push_back 到 obj +0xf0 的 timeline vector。

DVFS Timeline

DvfsEvent 流构建一个 vector<pair<u64 gtc, PState>>,即 convert 函数的输出引用参数,通过 __assign_with_size 赋值。PStatexprof enum {P_STATE_ACTIVE, P_STATE_INACTIVE, PSTATE_REQUEST_RECEIVED, PSTATE_REQUEST_COMPLETED, PSTATE_REQUEST_DROPPED}(五个字符串都已在 .rodata 中确认)。随后该 timeline 作为 Span<pair<u64,PState>> 传给 compute-trace converter,用芯片在各点观测到的 P-state 标注逐 instruction compute trace,即 DVFS overlay。它与 kDeviceTypeInfo 其他位置的静态 DVFS frequency ladder 闭环:ladder 是 operating point,DvfsEvent 流是观测到的逐 run P-state transition。

各代 Calibration Bundle

+0x360..+0x398 bundle 按 DeviceType 存放,从 kDeviceTypeInfo 逐字节读取:

Gen(row)+0x360+0x368+0x370+0x378+0x380+0x388+0x390+0x398
v7x(idx 12, 0x1c637e00.20.00.20.00302650
v6e(idx 13, 0x1c63c280.7859.040.8870.2250311150
(idx 10, 11)000003100
(其他行)00000000

四个 double 是 power/thermal calibration coefficient(按 rail 的 energy→W bias/scale):v7x 使用平坦的 0.2 对,v6e 使用更丰富的 0.785 / 9.04 / 0.887 / 0.225 曲线。四个 ulong 是 Get() 中作为 divisor / range 使用的各代 count:+0x388 = power meter 数量(v7x 上 30,v6e 上 31),+0x390 = thermal/throttle item 数量(v7x 上 26,v6e 上 11),+0x398 = sample/window count(50)。

NOTE — 与 perf-counter descriptor(仅 v7x)不同,firmware calibration bundle 在 v7x 和 v6e 上都有填充,另有两行只带有 +0x388 = 31。因此 firmware power/thermal/DVFS 层不是 v7x 专属;只有具名 HW perf-counter 层是。v6e 四系数曲线究竟是 polynomial(a0 + a1·x + …)还是独立的按 rail coefficient 尚未完全分离;Get() PowerLevel 数学使用 +0x10/+0x18 作为 bias/scale,让高阶 v6e 项(9.040.887)的角色保持低置信度。


尚未追踪

  • TCS / TensorCore counter 名称。 +0x2c8 base 0xa668a008 + ordinal*8 落入一个 gfc PerformanceCounterNameToString 不映射的 PerformanceCounterName band(对所有已采样 ordinal 返回空)。该 set 已识别(TCS、<28>0x10000000 flag),但其名称表在别处。
  • 完整 enum bit-layout。 base + ordinal*8 证明 counter ordinal 是低 bitfield(×8);高位的分区(哪些 bit = chiplet / die / unit instance,0xa5/0xa6/0xa7/0xd6 高 nibble 作为 subsystem domain 的含义)尚未 bit-slice。可通过扫描 20 个 ToString band 恢复。