Skip to content

Add PmcProbe: Apple Silicon PMU probe for lookup branch mispredicts - #36

Merged
hadashiA merged 5 commits into
mainfrom
claude/pmc-probe
Aug 28, 2026
Merged

hadashiA merged 5 commits into
mainfrom
claude/pmc-probe

Conversation

@hadashiA

Copy link
Copy Markdown
Owner

Adds sandbox/PmcProbe, a diagnostics harness that reads Apple Silicon PMU counters around the same lookup loops as ReadBenchmark, to verify that the timing gap between predictable and unpredictable key streams is caused by branch mispredictions rather than caches.

  • 3 node layouts (sorted digests + SIMD window / Eytzinger digests / no digests) x 3 key patterns (fixed / memorizable 1000-key sequence / never-repeating)
  • P/Invokes the private kperf / kperfdata frameworks (the machinery behind Instruments); C# port of ibireme's kpc_demo.c
  • Requires sudo, Apple Silicon only, dev-machine diagnostics — caveats documented in the README along with measured M5 results

Highlights from the M5 run (per lookup): mispredicts are ~0 whenever the predictor can memorize the key stream, 3.1 (digest+SIMD) / 6.1 (no digest) on truly random keys, and ~0 for the branch-free Eytzinger descent; the cycle deltas put one mispredict at ~40 effective cycles.

🤖 Generated with Claude Code

hadashiA and others added 5 commits August 24, 2026 13:07
A small harness that reads per-thread PMU counters (cycles, instructions,
branches, branch mispredicts) around the same lookup loops as
ReadBenchmark, across three node layouts (sorted digests + SIMD window,
Eytzinger digests, no digests) and three key patterns (fixed, memorizable
repeating sequence, never-repeating sequence).

Uses the private kperf/kperfdata frameworks via P/Invoke (the machinery
behind Instruments); requires sudo, Apple Silicon only — see the README
for usage, caveats, and measured M5 results.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Kpc.cs holds the kperf/kperfdata P/Invoke surface, Pmc.cs the event
setup and per-thread counter reads, Program.cs the benchmark driver.
No behaviour change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pmc.Read now returns a PmcCounters value instead of filling a ulong[].
The struct pins one 8-byte slot per event in EventNames order, exposes
an indexer over the slots, a subtraction operator for deltas, and owns
the markdown header/cell rendering that Program previously hand-rolled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The kernel fills the counter buffer in physical-slot order while
PmcCounters fields sit in event order; kpep's register map connects the
two. Init now verifies the map is the identity permutation (and probes
one short read) — when it is, Read hands the struct itself to
kpc_get_thread_counters with no scratch buffer or permute, and falls
back to the permuted path otherwise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hadashiA
hadashiA merged commit 6d9b45c into main Aug 28, 2026
1 check passed
@hadashiA
hadashiA deleted the claude/pmc-probe branch August 28, 2026 00:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant