Files
xvm/BENCHMARKS_RAW.txt
zeekay ed7ada69af v0.55.3 — fix size-dependent CPU↔Metal↔WGSL determinism divergence
Root cause: the v0.55.2 bench reported `execution_root` from the LAST
iteration of each backend's wall-clock loop. CPU ran 13 rounds; Metal ran
(3+10, 2+5, 1+3) per tier; WGSL ran (1+3) per tier. Because each call uses
`make_desc(round_idx)` which sets `height = 100 + round_idx`, the LAST
descriptor differed per backend, and `execution_root = keccak(parent ||
utxo_root || asset_root || tx_root || height)` therefore differed too. No
kernel divergence — the bench was comparing different rounds' results.

Fix: separate the determinism oracle from the wall-clock loop. The bench
runs an explicit canonical descriptor (`round=1, height=101`) on every
backend BEFORE the timed loops and prints `determinism: CPU == all GPU
backends @ round=1 (byte-equal)` (or a DETERMINISM FAIL if not). The timed
loops keep iterating round_idx for cache freshness; their per-iteration
roots are no longer compared cross-backend. xvm_diverge_probe (added) was
used to reproduce the v0.55.2 hex values exactly under the same per-backend
round_idx mismatch and confirm byte-equality under the same descriptor.

Test: extended xvm_determinism_test.cpp with test_size_sweep covering
small (1024/256), medium (4096/1024), large (12288/4096) 4-way (CPU/Metal/
WGSL) and xlarge (32768/8192) CPU-only (exceeds GPU arena cap of
kDefaultUtxoSlots=16384, kMaxTxs=4096). 15/15 expectations pass on every
backend pass.

Benchmark: numbers re-baselined in BENCHMARKS.md and BENCHMARKS_RAW.txt.
v0.55.2 → v0.55.3 wall-clock deltas: CPU small 26.2ms→36.8ms, CPU large
446ms→828ms, Metal large 31.2s→26.0s, WGSL small 13.8s→2.95s. Variance
is within run-to-run noise on a non-isolated host; the kernels are
unchanged.
2026-04-26 22:50:07 -07:00

51 lines
3.9 KiB
Plaintext

=== xvm-benchmark — XVM transition substrate wall-clock ===
warmup=3 measured=10 build=Release -O3 -DNDEBUG
backends:
CPU reference : enabled
default GPU : Apple M1 Max
WGSL/WebGPU : Apple M1 Max
=== small : 1024 UTXOs / 256 txs ===
canonical execution_root @ round=1 : 2b3f8b571d22e6d49dc6b4f8bdacde1d17d1b5fcbedcd954fdd5ddc2852b6d71 (CPU oracle)
determinism: CPU == all GPU backends @ round=1 (byte-equal)
CPU mean= 36.829 ms p50= 36.829 ms p95= 36.829 ms p99= 36.829 ms min= 36.829 ms max= 36.829 ms | 7.14K/s UTXOs/s 7.14K/s txs/s | 1.00x vs CPU | accept=256 reject=0
Apple M1 Max (Metal) mean= 499.537 ms p50= 499.537 ms p95= 499.537 ms p99= 499.537 ms min= 499.537 ms max= 499.537 ms | 514.49 /s UTXOs/s 514.49 /s txs/s | 0.07x vs CPU | accept=256 reject=0
Apple M1 Max (WGSL) mean= 2.954 s p50= 2.954 s p95= 2.954 s p99= 2.954 s min= 2.954 s max= 2.954 s | 86.70 /s UTXOs/s 86.70 /s txs/s | 0.01x vs CPU | accept=256 reject=0
per-kernel (CPU, avg of 10):
UTXOInputCheck+TransitionApply : 12.286 ms
XAssetTransition (empty pass) : 2.449 ms
XRootUpdate : 10.098 ms
=== medium : 4096 UTXOs / 1024 txs ===
canonical execution_root @ round=1 : 0f35254a5e59e586c05405c195d3147a42ee20725aea3d1b57cb6fc57472bfa7 (CPU oracle)
determinism: CPU == all GPU backends @ round=1 (byte-equal)
CPU mean= 166.955 ms p50= 166.955 ms p95= 166.955 ms p99= 166.955 ms min= 166.955 ms max= 166.955 ms | 6.19K/s UTXOs/s 6.19K/s txs/s | 1.00x vs CPU | accept=1024 reject=0
Apple M1 Max (Metal) mean= 2.578 s p50= 2.578 s p95= 2.578 s p99= 2.578 s min= 2.578 s max= 2.578 s | 398.98 /s UTXOs/s 398.98 /s txs/s | 0.06x vs CPU | accept=1024 reject=0
Apple M1 Max (WGSL) mean= 13.690 s p50= 13.690 s p95= 13.690 s p99= 13.690 s min= 13.690 s max= 13.690 s | 77.80 /s UTXOs/s 77.80 /s txs/s | 0.01x vs CPU | accept=1024 reject=0
per-kernel (CPU, avg of 10):
UTXOInputCheck+TransitionApply : 59.426 ms
XAssetTransition (empty pass) : 9.855 ms
XRootUpdate : 39.819 ms
=== large : 12288 UTXOs / 4096 txs ===
canonical execution_root @ round=1 : caf4ea64c6f1d0b1722ac0ea63752d3af45c8b2668a36f2ecb44f7643dda63bb (CPU oracle)
determinism: CPU == all GPU backends @ round=1 (byte-equal)
CPU mean= 828.322 ms p50= 828.322 ms p95= 828.322 ms p99= 828.322 ms min= 828.322 ms max= 828.322 ms | 4.99K/s UTXOs/s 4.99K/s txs/s | 1.00x vs CPU | accept=4096 reject=0
Apple M1 Max (Metal) mean= 25.991 s p50= 25.991 s p95= 25.991 s p99= 25.991 s min= 25.991 s max= 25.991 s | 160.38 /s UTXOs/s 160.38 /s txs/s | 0.03x vs CPU | accept=4096 reject=0
Apple M1 Max (WGSL) mean= 62.039 s p50= 62.039 s p95= 62.039 s p99= 62.039 s min= 62.039 s max= 62.039 s | 67.20 /s UTXOs/s 67.20 /s txs/s | 0.01x vs CPU | accept=4096 reject=0
per-kernel (CPU, avg of 10):
UTXOInputCheck+TransitionApply : 352.792 ms
XAssetTransition (empty pass) : 38.964 ms
XRootUpdate : 118.852 ms
=== xlarge : 32768 UTXOs / 8192 txs ===
canonical execution_root @ round=1 : 3dd08800de820de06e65103e58403dd76365b87ee0c4d3d7f8323a6bb623249c (CPU oracle)
determinism: CPU == all GPU backends @ round=1 (byte-equal)
CPU mean= 3.890 s p50= 3.890 s p95= 3.890 s p99= 3.890 s min= 3.890 s max= 3.890 s | 2.29K/s UTXOs/s 2.29K/s txs/s | 1.00x vs CPU | accept=8191 reject=1
per-kernel (CPU, avg of 10):
UTXOInputCheck+TransitionApply : 1.447 s
XAssetTransition (empty pass) : 111.084 ms
XRootUpdate : 335.866 ms
=== xvm-benchmark complete ===