Native CPU-PMU Integration
How to build a native CPU-performance-monitoring data layer for the sparkles benchmarking harness — sparkles:test-runner --bench and the wired runtime bench. The survey grounds the Linux stack (perf_event_open and its decoder libraries — elfutils, libtraceevent, libnuma), maps it onto ARMv8+ and RISC-V, surveys the alternative acquisition APIs on Windows and macOS, and lands in a capability matrix, an audit baseline, and a milestoned backend proposal. Every page is grounded twice over: claims carry pinned repo@commit path:line locators or recorded experiments, and locally-demonstrable behavior is backed by runnable probes CI compiles and runs.
Last reviewed: July 11, 2026
This survey answers ten questions:
- What does
perf_event_openactually provide — counting, sampling, and the contracts underneath (groups, multiplexing, the ring buffer, rdpmc)? → linux-perf-events - How do the four Linux decoder libraries divide the work, and where do they stop? → elfutils, libtraceevent, libnuma
- How does precise memory sampling work on each vendor engine (IBS, PEBS, SPE), and how does a sampled data address become a NUMA node? → precise-sampling
- How does the model map onto ARMv8+/ARMv9 — PMUv3's event space, SPE, BRBE, big.LITTLE, uncore — and what is Apple Silicon really? → arm
- How does it map onto RISC-V, and which capabilities simply do not exist there yet? → riscv
- What can a Windows profiler use without a kernel driver, and what only with one? → windows
- What can a macOS process measure at each privilege level, and what is fenced behind root, entitlements, and the event allowlist? → macos
- How do human event names become hardware encodings, and which naming layer covers which ISA and OS? → event-naming
- Where does the sparkles harness stand today against all of the above? → sparkles-baseline + the delta table
- What should sparkles build? → backend-proposal
The seven concerns
Every subject in the tree is analyzed against the same seven-concern spine — where a concern does not apply, the page says so, because the absence of a capability is itself a finding:
- Scalar counting — groups, exactness, multiplexing.
- Overflow/IP sampling — periods, PMIs, ring buffers.
- Precise data-source/address sampling — skidless engines, latency, data addresses.
- Code-space decode & symbolization — address-space models, debug info, unwinding.
- Event-space & tracing — tracepoints/ETW/kdebug, branch records.
- NUMA & topology — nodes, uncore scoping, page→node oracles.
- Event naming & encoding — name→selector tables and their coverage boundaries.
Master catalog
| Subject | What it is | Concern focus | Verification bed | Link |
|---|---|---|---|---|
| Concepts | the tree's shared vocabulary | all | — | concepts.md |
Linux perf_events | the acquisition hub (reference model) | 1, 2 | x86_64-linux hw | linux-perf-events.md |
| elfutils | code-space decoder (libelf/libdw/libdwfl) | 4 | x86_64-linux hw | elfutils.md |
| libtraceevent | event-space decoder (tracefs format) | 5 | source | libtraceevent.md |
| libnuma | topology/placement decoder | 6 | x86_64-linux hw (single-node) | libnuma.md |
| Precise sampling | IBS · PEBS · SPE → one ABI; address→node | 3, 6 | IBS hw; PEBS/SPE source | precise-sampling.md |
| ARMv8+ | PMUv3, SPE, BRBE, big.LITTLE, uncore, Apple | 1–7 mapping | source; Apple aarch64-darwin hw | arm.md |
| RISC-V | SBI indirection, Sscofpmf, CTR | 1–7 mapping (absences) | source + spec | riscv.md |
| Windows | HCP, ETW, ring-0 drivers, PDB, Win32 NUMA | 1–7 mapping | docs + open consumers | windows.md |
| macOS | kpc/kperf, rusage, Instruments, dyld/dSYM | 1–7 mapping | aarch64-darwin hw | macos.md |
| Event naming | libpfm4, PAPI, LIKWID, vendor tables | 7 | x86_64-linux hw | event-naming.md |
| Comparison | capability matrix · trade-offs · delta table | synthesis | — | comparison.md |
| sparkles baseline | today's counter layer, as observed | audit target | in-repo | sparkles-baseline.md |
| Backend proposal | milestoned per-OS acquisition core, in D | design | — | backend-proposal.md |
Taxonomies
By ISA
| ISA | Counting model | Precise engine | Branch records | Pages |
|---|---|---|---|---|
| x86_64 (AMD) | perf_event_open, 6 PMCs | IBS (skid 0) | LBR | linux, precise |
| x86_64 (Intel) | perf_event_open, fixed+GP | PEBS (precise_ip 1–3) | LBR | precise, naming |
| ARMv8+/v9 | PMUv3 (PMCEID-probed), per-cluster PMUs | SPE (AUX) | BRBE | arm |
| RISC-V | SBI-mediated mhpmcounter | none | CTR (ratified, no consumer) | riscv |
| Apple Silicon | proprietary CPMU, 2 fixed + 8 | none exposed | none exposed | arm §Apple, macos |
By OS
| OS | Acquisition surface | Event policy | Decode stack | Page |
|---|---|---|---|---|
| Linux | one syscall, all modes | open selectors, paranoid-gated | MMAP2 + DWARF (elfutils) | linux |
| Windows | HCP + ETW + closed ring-0 drivers | curated + global registration | image-load events + PDB (DbgHelp) | windows |
| macOS | kpc/kperf (root) · rusage (unpriv) · Instruments | kernel allowlist, even for root | dyld map + dSYM (CoreSymbolication) | macos |
By verification level
| Level | What carries it |
|---|---|
[hw-verified: x86_64-linux] | Linux counting/sampling/unwinding, IBS, libpfm4 round trip, NUMA round trip — the five probes below |
[hw-verified: aarch64-darwin] | kpep catalogs, kpc EPERM matrix, rusage counting, xctrace, dyld/atos — mac-bsn transcripts in macos/arm |
[source-verified] | ARM-Linux drivers, RISC-V kernel/SBI/firmware, PEBS, xnu/dtrace, krabsetw, all pinned repos |
[literature] | vendor docs (saved), gated specs cited by section |
Milestones
When the key capabilities landed. Coarse dates are [literature]; entries verified in this survey's sources are tagged.
| When | What |
|---|---|
| ~2000 | Intel PEBS ships with NetBurst (Pentium 4) [literature] |
| 2007 | AMD IBS ships with Family 10h (Barcelona) [literature] |
| 2009 | Linux 2.6.31 merges perf_event_open [literature]; Windows 7 ships HCP thread profiling (min-version per the API docs) [source-verified] |
| 2016 | Armv8.2 defines SPE [literature] |
| 2019 | Win10 1903 allows raw ProfileSource registration; 19H1 makes ETW LBR public [source-verified] (docs); Armv8.5/PMUv3p5 makes event counters 64-bit [source-verified] |
| 2021 | RISC-V Sscofpmf ratified; SBI 0.3 adds the PMU extension [literature]; Armv9.2 defines BRBE [source-verified] |
| 2024-11-22 | RISC-V CTR (Smctr/Ssctr) v1.0 ratified [source-verified] — still no Linux consumer at v7.1-rc6 |
| 2024 | Apple M4 remaps its common PMU events onto PMUv3 architected numbers [hw-verified: aarch64-darwin] |
The runnable probes
Standalone dub single-file programs under examples/; CI compiles and runs each (they SKIP cleanly on hosts lacking a capability). Environment: Linux 6.18.26, AMD Ryzen 9 7940HX, LDC 1.41.
| Probe | Demonstrates | Backs |
|---|---|---|
| counting-group.d | grouped IPC (exact) + forced multiplex scaling | linux concern 1 |
| sampling-symbolize.d | ring-buffer IP sampling → libdwfl symbolization | linux concern 2/4 |
| unwind-stack-user.d | DWARF-CFI unwind of a frame-pointer-less build | linux/elfutils |
| mem-latency-numa.d | IBS data-source/latency sampling + page→node oracles | precise |
| pfm4-name-roundtrip.d | libpfm4 name→perf_event_attr→open→count | naming |
Quick navigation
- "I'm designing the sparkles backend" — concepts → sparkles-baseline → linux-perf-events → event-naming → comparison (matrix + delta) → backend-proposal; add precise-sampling before milestone 5 and macos/windows before 3/4.
- "Why is my profile lying to me?" — concepts § skid → precise-sampling → linux § build-id hazard.
- "What breaks off x86-Linux?" — arm → riscv → windows → macos → comparison § open questions.
- Vocabulary lookup — concepts.md.
Sources
Per-page Sources sections carry the primary references; repos are pinned by SHA and papers archived locally (see each deep-dive). The five probes and the mac-bsn transcripts are the survey's own experimental evidence; experiment environments are recorded alongside every quoted output.