Expand description
PDH GPU counters: instance-name grammar, aggregation math, and (on Windows) the shared process-wide query both Windows backends read from.
Structs§
- Engine
Headline - One adapter’s busiest engine: the device-headline utilization (§3.4).
- Instance
Luid - The two hex DWORDs of an instance-name
luidtoken, in printed order. - Parsed
Instance - One parsed PDH GPU counter-instance name. Every field optional: the three counter
families share one grammar but carry different token subsets
(
GPU Engine= pid+luid+phys+eng+engtype,GPU Process Memory= pid+luid+phys,GPU Adapter Memory= luid+phys). - PdhSnapshot
- One formatted collection of every GPU counter stream — pure data, so the
aggregation functions above are testable from scripted values on any OS. Built on
Windows by [
SharedPdh::snapshot]; both Windows backends read the same snapshot. - PidUtil
- One pid’s utilization on one adapter (§2.4/§3.5).
Constants§
- PDH_
CSTATUS_ INVALID_ DATA - Counter exists but its value could not be validated (first-sample case per item).
- PDH_
CSTATUS_ NEW_ DATA PDH_CSTATUS_NEW_DATA: valid value, instance appeared since the previous collect.- PDH_
CSTATUS_ NO_ COUNTER - Object exists but the counter does not (older WDDM driver).
- PDH_
CSTATUS_ NO_ INSTANCE - No instances right now (e.g. no process currently touches the GPU). Normal.
- PDH_
CSTATUS_ NO_ OBJECT - No such performance object — exactly what a GPU-less CI runner reports for
GPU Engine(no WDDM 2.0 GPU/driver in the session). - PDH_
INVALID_ DATA - Query-level first-sample/invalid-data case. Normal.
- PDH_
MORE_ DATA - Buffer too small — the “call again with a bigger buffer” half of the two-call pattern, not a failure.
- PDH_
NO_ DATA - The query has no data yet (first collection of rate counters). Normal.
- PDH_OK
ERROR_SUCCESS— andPDH_CSTATUS_VALID_DATA, which shares the value 0.- PDH_
QUERY_ PERF_ DATA_ TIMEOUT - The perf-data provider timed out — a transient miss, NOT a lost device.
Functions§
- adapter_
bytes - Adapter-level byte total (for the
GPU Adapter Memorystreams) for one adapter, summed across its phys/part instances.Nonewhen nothing matched — a GPU with no counter is “unknown”, not “0 bytes used”. - device_
util - Device-headline utilization for one adapter: the busiest single engine after
per-engine pid-summing — deliberately Task-Manager-Performance-tab-comparable
(§3.4).
Nonewhen no instance matched: GPU-less runner, first PDH sample, or an unmatched LUID — all normal. - engtype_
util - Busy% of the busiest engine of one engtype (e.g.
VideoEncode/VideoDecodefor the encoder/decoder fields), after per-engine pid-summing. Name comparison is case-insensitive (the engtype set is open; drivers vary casing). Absent engtype →None(§3.4) — never 0, which would claim an idle encoder this GPU may not have. - item_
value_ is_ trustworthy - Per-item
CStatusgate: only VALID/NEW values are trusted (§3.2 “per-item CStatus checked before trusting any value”). Anything else means this item isNonethis tick — not the whole snapshot. - parse_
instance - Parse a PDH GPU counter-instance name, e.g.
pid_1234_luid_0x00000000_0x0000C739_phys_0_eng_3_engtype_3D. - per_
pid_ bytes - Per-pid byte totals (for the
GPU Process MemoryDedicated/Shared Usage streams) on one adapter, summed across a pid’s phys/part instances. Values are raw counter doubles; negatives (a provider glitch) clamp to 0 rather than wrap. - per_
pid_ util - Per-pid utilization on one adapter: max across each pid’s engine instances on this LUID. Unattributed instances (LUID mismatch/unparsed) are skipped.
- status_
is_ normal_ absence - The §3.2 contract: each of these maps to
None(plus at most one collector self-honesty event, emitted upstream), never anErr. A refactor that starts treating any of them as a failure breaks the GPU-less-CI-runner path — that is the case the any-OS unit test pins.