Skip to content

fix: stop the WASM engine counting bus accesses on top of per-instruction cycles - #218

Merged
stid merged 3 commits into
masterfrom
fix/wasm-cycle-double-count
Sep 4, 2026
Merged

fix: stop the WASM engine counting bus accesses on top of per-instruction cycles#218
stid merged 3 commits into
masterfrom
fix/wasm-cycle-double-count

Conversation

@stid

@stid stid commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Closes #215

Summary

  • read_byte_from_bus / write_byte_to_bus in wasm-cpu/src/cpu.rs each added a cycle while every opcode arm also added the instruction's full documented count, so step_with_bus reported ~2× (NOP=3, LDA #=4, LDA zp=6, LDA (zp),Y=10). Clock budgets against that value, so the WASM engine executed about half the instructions per emulated second that the JS engine did.
  • Fix: drop the two per-access increments (the issue's option 2). The arms alone now match the datasheet and the JS engine's model; IRQ/NMI stay a flat 7 in both engines.
  • Tests (TDD, committed red first): compareEngines now asserts the cycle count returned by each performSingleStep matches, and a new documented-cycle battery holds both engines to the datasheet (NOP, LDA imm/zp/abs, abs,X and (zp),Y with and without page cross, STA abs,X, INC abs, JSR/RTS, branch not-taken/taken/page-cross, PHA/PLA). Before the fix: 23/27 red on cycles only.
  • Docs: the wasm-performance.md "~14×" headline was measured with the inflated counter. Re-ran BENCH=1 with honest counting → WASM 443 M vs JS 56 M cycles/s = ~7.8× (instr/s, never affected, says ~8.5×). Table + CLAUDE.md updated.
  • Version 4.51.9 → 4.51.12 (fix: add missing spacing.xxs token so py-xxs badges get their padding #216 and chore: refresh dependencies (npm minor/patch, Cargo.lock, GitHub Actions) #217 take .10/.11; whichever merges later needs a one-line rebase of src/version.ts).

Verification against real WASM (not just cargo check)

Run with yarn dev:vite serving the rebuilt release build, per cpu_test_guidelines.md:

  • engine-parity suite: 27/27 (was 23 red)
  • all src/core/cpu-engines/__tests__ suites: 75 passed, 1 skipped (benchmark gate)
  • yarn test:ci with the server up: 818 passed, 1 skipped — the parity suites ran for real inside the gate
  • cargo check clean; yarn wasm:test shows only the documented wasm-bindgen native-target panics (pre-existing)

LCD: Standard lane, JOURNAL at docs/lcd/work/wasm-cycle-double-count/.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VDq6at6VpsyBxLqB8wBnDT

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 12 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 39761a1e-3f90-4a49-a6e4-a796754652ca

📥 Commits

Reviewing files that changed from the base of the PR and between fc58be0 and 53f8f24.

📒 Files selected for processing (7)
  • CLAUDE.md
  • docs/active/wasm-performance.md
  • docs/lcd/triage-log.md
  • docs/lcd/work/wasm-cycle-double-count/JOURNAL.md
  • src/core/cpu-engines/__tests__/engine-parity.vitest.test.ts
  • src/version.ts
  • wasm-cpu/src/cpu.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

stid and others added 3 commits September 3, 2026 23:11
… engines (#215)

compareEngines now compares the cycle count each engine returns from
performSingleStep, and a new battery holds both engines to the datasheet
(NOP, LDA modes incl. page-cross, STA abs,X, INC abs, JSR/RTS, branches,
PHA/PLA). Against real WASM this is RED: the engine reports NOP=3,
LDA #=4, LDA zp=6 because the bus helpers and the opcode arms both count.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDq6at6VpsyBxLqB8wBnDT
…tion cycles

read_byte_from_bus / write_byte_to_bus each added a cycle while every
opcode arm also added the instruction's full documented count, so
step_with_bus reported roughly twice the real figure (NOP=3, LDA #=4,
LDA (zp),Y=10). Clock budgets against that value, so the WASM engine ran
about half the instructions per emulated second that the JS engine did.

Drop the per-access increments; the arms alone now match the datasheet
and the JS engine's model (IRQ/NMI stay at a flat 7 in both). Verified
against the real WASM build: parity 27/27 incl. the new documented-cycle
battery, all engine suites 75/75.

Re-ran the headless benchmark with honest counting: WASM is ~7.8x JS on
cycles/s (instr/s ~8.5x), not the ~14x the docs quoted, which was
measured with the inflated counter. Docs and CLAUDE.md updated.

Closes #215

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDq6at6VpsyBxLqB8wBnDT
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VDq6at6VpsyBxLqB8wBnDT
@stid
stid force-pushed the fix/wasm-cycle-double-count branch from 53f8f24 to adb4fa9 Compare September 4, 2026 06:12
@stid
stid merged commit f904eb7 into master Sep 4, 2026
5 checks passed
@stid
stid deleted the fix/wasm-cycle-double-count branch September 4, 2026 06:12
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.

WASM engine double-counts cycles: bus helpers increment and opcode arms add the full count

1 participant