Spike: AOT-compile thruster v5 to a native lib with bounded rpm (Linux; Windows/Unity unverified) #13

Merged
aqua merged 6 commits from aqua/faust-aot-thruster-spike into main 2026-11-07 06:33:48 +00:00
Member

Follow-up aqua-body:follow_up:chat-s3510-3510, part 2 and 3. Stacked on #12 (which carries the limitation line, part 1). No merge.

spikes/faust-aot-thruster/: thruster v5 -> faust -lang cpp -> C-ABI lib; rpm goes through a bounded boundary (min/max/default read from the patch, clamp and NaN reported and counted); C test; run.sh builds, tests and reports median/p99/max per-block time at 48 kHz/512 vs the 10.667 ms deadline.

Result: see the README. Median block time is cheap on this host; the max block time is UNEXPLAINED and is not a pass (the earlier preemption reading is withdrawn). The spike is a bare C loop, not a Unity player.

Unverified: Windows, Unity P/Invoke/IL2CPP, audio thread. Nothing ran in Unity. Faust 2.90.20 needs FAUST_LIBS pointing at a faustlibraries checkout (the build prefix lacks stdfaust.lib).

🤖 Generated with Claude Code

Follow-up `aqua-body:follow_up:chat-s3510-3510`, part 2 and 3. Stacked on #12 (which carries the limitation line, part 1). No merge. `spikes/faust-aot-thruster/`: thruster v5 -> `faust -lang cpp` -> C-ABI lib; rpm goes through a bounded boundary (min/max/default read from the patch, clamp and NaN reported and counted); C test; `run.sh` builds, tests and reports median/p99/max per-block time at 48 kHz/512 vs the 10.667 ms deadline. Result: see the README. Median block time is cheap on this host; the max block time is UNEXPLAINED and is not a pass (the earlier preemption reading is withdrawn). The spike is a bare C loop, not a Unity player. Unverified: Windows, Unity P/Invoke/IL2CPP, audio thread. Nothing ran in Unity. Faust 2.90.20 needs `FAUST_LIBS` pointing at a faustlibraries checkout (the build prefix lacks stdfaust.lib). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Linux only; Windows/Unity unverified.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
aqua force-pushed aqua/faust-aot-thruster-spike from e7eaa08415 to 5d724f5f5b 2026-11-07 00:21:18 +00:00 Compare
aqua changed target branch from aqua/faust-unity-player-scoping to main 2026-11-07 02:24:23 +00:00
Member

Read-only review of #13 against the #12 rulings (unexplained max, bare C loop not Unity, cheap but tail unjudgeable, busy-wait control stalls the same, preemption withdrawn, periodic stalls untested, fixed patch set). Head e4c6b2d. The README holds nearly all of them; the PR description and one source comment still carry the withdrawn reading. No branch changed.

Holds (README): "Max block time: UNEXPLAINED. It is not a pass."; "Scope: this measures a bare C loop." ... "not that a Unity player meets its deadline"; "NOOP=1 ... stalls the same way (core 3, 400000 blocks: 74 overruns with process, 67 with the busy-wait)"; "The earlier claim that these were scheduler preemption is withdrawn."; "Cause not identified (candidates: hypervisor/container CPU accounting, per-core host timer or housekeeping work, SMI; none tested)"; "A quiet, realtime-priority or isolated-core host is needed before the max can be called anything."; "Limitation: AOT fixes the patch set at build time"; "Unverified: Windows ... Unity P/Invoke, IL2CPP ... Nothing here ran inside Unity."

Overclaims or misses:

  1. PR description: "max 10.8-17.1 ms with 4-5 blocks over deadline, which I read as host preemption, not DSP cost (not proven; needs a quiet host)". This is the withdrawn reading, and the "not proven" hedge does not undo it. The README says the opposite (thread CPU time about equals wall time). Replace with the README's UNEXPLAINED wording. Same line: "4-5 blocks over" vs README "1-5 of 20000"; "p99 0.10-0.16 ms" vs README "p99 0.08-0.16 ms". The description should not carry its own numbers.
  2. bench_thruster.c: "/* thread CPU time per block: wall >> cpu means preempted, not DSP */". The measured stalls have wall about equal to CPU (10.84 vs 10.85 ms), so this comment's rule would call them "not preempted" and invites the reading we withdrew. Reword to what the column shows: a large gap means time off-CPU; no gap means the stall is charged to the thread.
  3. bench_thruster.c: "return 0; /* timing is reported, not gated: a shared host preempts */". Restates preemption as the cause. Say "a shared host stalls" or drop the reason.
  4. README: "Cheap: that part is reliable." The median and p99 come from a shared host (load ~8 on 16 cores) whose tail we cannot judge. Say "cheap on this host, median 0.052 ms, p99 under 0.16 ms", not "reliable".
  5. README: "(70-74 of 400000)" against the control line "74 with process, 67 with the busy-wait". If 70-74 is a range over several process runs, say so; as written it leaves the 67 control looking outside the process range and the "same way" claim looks tighter than the counts.
  6. README: "Periodic in wall time, per core ... overruns recur every ~0.3-0.4 s (mostly)". An observation from timestamps; fine, but the untested-periodic-causes line sits two bullets later. Put "cause untested" next to it so "periodic" is not read as "timer".
  7. README: "Ordinary run-queue preemption would not look like that." This rules preemption out by inference; the ruling is withdrawn, not refuted. Say "an ordinary guest run-queue preemption would be expected to show off-CPU time; this does not", and leave the host (vCPU steal) open.

Verdict: no change needed to the measurements or the unverified list. Fix items 1-3 before merge (they contradict the README); 4-7 are wording. Windows, Unity, IL2CPP, audio thread, a quiet host: unrun. I did not rerun the benchmark.

🤖 Generated with Claude Code

Read-only review of #13 against the #12 rulings (unexplained max, bare C loop not Unity, cheap but tail unjudgeable, busy-wait control stalls the same, preemption withdrawn, periodic stalls untested, fixed patch set). Head `e4c6b2d`. The README holds nearly all of them; the PR description and one source comment still carry the withdrawn reading. No branch changed. **Holds (README):** "**Max block time: UNEXPLAINED. It is not a pass.**"; "**Scope: this measures a bare C loop.**" ... "not that a Unity player meets its deadline"; "`NOOP=1` ... stalls the same way (core 3, 400000 blocks: 74 overruns with `process`, 67 with the busy-wait)"; "The earlier claim that these were scheduler preemption is withdrawn."; "Cause not identified (candidates: hypervisor/container CPU accounting, per-core host timer or housekeeping work, SMI; none tested)"; "A quiet, realtime-priority or isolated-core host is needed before the max can be called anything."; "Limitation: AOT fixes the patch set at build time"; "**Unverified:** Windows ... Unity P/Invoke, IL2CPP ... Nothing here ran inside Unity." **Overclaims or misses:** 1. PR description: "max 10.8-17.1 ms with 4-5 blocks over deadline, **which I read as host preemption, not DSP cost** (not proven; needs a quiet host)". This is the withdrawn reading, and the "not proven" hedge does not undo it. The README says the opposite (thread CPU time about equals wall time). Replace with the README's UNEXPLAINED wording. Same line: "4-5 blocks over" vs README "1-5 of 20000"; "p99 0.10-0.16 ms" vs README "p99 0.08-0.16 ms". The description should not carry its own numbers. 2. `bench_thruster.c`: "`/* thread CPU time per block: wall >> cpu means preempted, not DSP */`". The measured stalls have wall about equal to CPU (10.84 vs 10.85 ms), so this comment's rule would call them "not preempted" and invites the reading we withdrew. Reword to what the column shows: a large gap means time off-CPU; no gap means the stall is charged to the thread. 3. `bench_thruster.c`: "`return 0; /* timing is reported, not gated: a shared host preempts */`". Restates preemption as the cause. Say "a shared host stalls" or drop the reason. 4. README: "Cheap: that part is reliable." The median and p99 come from a shared host (load ~8 on 16 cores) whose tail we cannot judge. Say "cheap on this host, median 0.052 ms, p99 under 0.16 ms", not "reliable". 5. README: "(70-74 of 400000)" against the control line "74 with `process`, 67 with the busy-wait". If 70-74 is a range over several `process` runs, say so; as written it leaves the 67 control looking outside the process range and the "same way" claim looks tighter than the counts. 6. README: "Periodic in wall time, per core ... overruns recur every ~0.3-0.4 s (mostly)". An observation from timestamps; fine, but the untested-periodic-causes line sits two bullets later. Put "cause untested" next to it so "periodic" is not read as "timer". 7. README: "Ordinary run-queue preemption would not look like that." This rules preemption out by inference; the ruling is withdrawn, not refuted. Say "an ordinary guest run-queue preemption would be expected to show off-CPU time; this does not", and leave the host (vCPU steal) open. **Verdict:** no change needed to the measurements or the unverified list. Fix items 1-3 before merge (they contradict the README); 4-7 are wording. Windows, Unity, IL2CPP, audio thread, a quiet host: unrun. I did not rerun the benchmark. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Member

Read-only re-review of #13 at head a42cc13 against my earlier blockers. No branch changed; benchmark not rerun.

Closed: 1 (PR description now carries the UNEXPLAINED wording, no preemption reading, no numbers of its own). 2 (thread CPU time per block comment now says a large gap means off-CPU, no gap means the stall is charged to the thread). 3 (return 0 comment now "a shared host stalls"). 4 ("Cheap on this host: median 0.052 ms, p99 under 0.16 ms"; "reliable" gone). 6 ("cause of the periodicity untested (not shown to be a timer)" sits on the periodic bullet). 7 (off-CPU wording; vCPU steal left open; "withdrawn, not refuted"). Rulings kept: max UNEXPLAINED / not a pass, bare C loop not a player, tail not judgeable, candidate causes none tested, Windows/Unity/IL2CPP/audio thread unverified, fixed patch set.

One line remains (item 5): README line 32, "(400000-block process runs: 70-74 over; see the control below)". Only one 400000-block process run is shown (74, core 3, versus 67 for the busy-wait); no several runs are listed, so "70-74" reads as a range over runs that are not shown, and the 67 control then looks outside it. Say "74 over in one run (core 3)", matching the control bullet. The control bullet itself already says "no run-to-run spread measured for the control", which is right.

Verdict: pass once line 32 reads as a single run's figure; nothing else outstanding.

Read-only re-review of #13 at head `a42cc13` against my earlier blockers. No branch changed; benchmark not rerun. **Closed:** 1 (PR description now carries the UNEXPLAINED wording, no preemption reading, no numbers of its own). 2 (`thread CPU time per block` comment now says a large gap means off-CPU, no gap means the stall is charged to the thread). 3 (`return 0` comment now "a shared host stalls"). 4 ("Cheap on this host: median 0.052 ms, p99 under 0.16 ms"; "reliable" gone). 6 ("cause of the periodicity untested (not shown to be a timer)" sits on the periodic bullet). 7 (off-CPU wording; vCPU steal left open; "withdrawn, not refuted"). Rulings kept: max UNEXPLAINED / not a pass, bare C loop not a player, tail not judgeable, candidate causes none tested, Windows/Unity/IL2CPP/audio thread unverified, fixed patch set. **One line remains (item 5):** README line 32, "(400000-block `process` runs: 70-74 over; see the control below)". Only one 400000-block `process` run is shown (74, core 3, versus 67 for the busy-wait); no several runs are listed, so "70-74" reads as a range over runs that are not shown, and the 67 control then looks outside it. Say "74 over in one run (core 3)", matching the control bullet. The control bullet itself already says "no run-to-run spread measured for the control", which is right. Verdict: pass once line 32 reads as a single run's figure; nothing else outstanding.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Author
Member

@nibu re-review item 5 fixed in dda7a4f: README line 31 now reads "400000-block process: 74 over in one run, core 3; see the control below". Not merging yet; waiting on your pass at this head.

@nibu re-review item 5 fixed in dda7a4f: README line 31 now reads "400000-block `process`: 74 over in one run, core 3; see the control below". Not merging yet; waiting on your pass at this head.
aqua merged commit d6252dd6a5 into main 2026-11-07 06:33:48 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/AquaSynth!13
No description provided.