Benchmark: pinky

November 11, 2024 · View on GitHub

This benchmark is a cycle-accurate NES emulator, running a real, homebrew NES game. (source code)

Oneshot execution (for pinky)

These benchmarks measure the end-to-end time that it takes to run the program a single time, including compilation and initialization.

VMTimevs fastest
(bare metal)33.007ms ± 0.014ms1.00x
PolkaVM (64-bit, recompiler)55.408ms ± 0.051ms1.68x
PolkaVM (32-bit, recompiler)57.264ms ± 0.025ms1.73x
PolkaVM (32-bit, recompiler, async gas)63.773ms ± 0.878ms1.93x
PolkaVM (64-bit, recompiler, async gas)63.897ms ± 0.099ms1.94x
PolkaVM (32-bit, recompiler, sync gas)69.818ms ± 0.187ms2.12x
PolkaVM (64-bit, recompiler, sync gas)70.208ms ± 0.755ms2.13x
Wasmtime (cranelift)116.002ms ± 0.329ms3.51x
Wasmtime (winch)117.121ms ± 2.528ms3.55x
Wasmtime (cranelift, epoch interruption)132.056ms ± 0.467ms4.00x
Wasmer (singlepass)137.832ms ± 0.287ms4.18x
Wasmtime (cranelift, fuel metering)161.383ms ± 0.569ms4.89x
Solana RBPF789.195ms ± 6.903ms23.91x
Wasm3884.142ms ± 1.092ms26.79x
Wasmi (lazy translation, checked)1.021 s ± 0.001s30.92x
Wasmi (eager, checked)1.022 s ± 0.002s30.96x
Wasmi (lazy, checked)1.023 s ± 0.001s30.99x
CKB VM (ASM)1.357 s ± 0.001s41.11x
PolkaVM (64-bit, interpreter)1.689 s ± 0.002s51.19x
PolkaVM (32-bit, interpreter)1.877 s ± 0.002s56.87x
CKB VM (non-ASM)10.006 s ± 0.014s303.14x

Execution time (for pinky)

These benchmarks measure the execution time of the benchmark, without the time it takes to compile or initialize it.

VMTimevs fastest
(bare metal)3.714ms ± 0.004ms1.00x
Wasmtime (cranelift)5.776ms ± 0.006ms1.56x
PolkaVM (64-bit, recompiler)6.422ms ± 0.156ms1.73x
PolkaVM (32-bit, recompiler)6.576ms ± 0.005ms1.77x
Wasmtime (cranelift, epoch interruption)6.577ms ± 0.022ms1.77x
PolkaVM (32-bit, recompiler, async gas)7.177ms ± 0.002ms1.93x
PolkaVM (64-bit, recompiler, async gas)7.345ms ± 0.148ms1.98x
PolkaVM (64-bit, recompiler, sync gas)7.957ms ± 0.083ms2.14x
PolkaVM (32-bit, recompiler, sync gas)8.188ms ± 0.156ms2.20x
Wasmtime (cranelift, fuel metering)8.324ms ± 0.072ms2.24x
Wasmtime (winch)10.773ms ± 0.086ms2.90x
Wasmer (singlepass)14.466ms ± 0.059ms3.89x
Solana RBPF80.809ms ± 0.539ms21.76x
Wasm396.046ms ± 0.159ms25.86x
Wasmi (lazy, checked)111.955ms ± 0.090ms30.14x
Wasmi (eager, checked)112.025ms ± 0.155ms30.16x
Wasmi (lazy translation, checked)112.193ms ± 0.104ms30.21x
CKB VM (ASM)144.825ms ± 1.254ms38.99x
PolkaVM (64-bit, interpreter)190.510ms ± 7.636ms51.29x
PolkaVM (32-bit, interpreter)203.905ms ± 0.117ms54.90x
CKB VM (non-ASM)1.106 s ± 0.024s297.84x

Compilation time (for pinky)

These benchmarks measure the time it takes to compile a given program by the VM.

VMTimevs fastest
PolkaVM (32-bit, interpreter)1.323µs ± 0.001µs1.00x
PolkaVM (64-bit, interpreter)1.358µs ± 0.001µs1.03x
Wasmi (lazy, checked)89.733µs ± 2.832µs67.80x
PolkaVM (64-bit, recompiler)167.553µs ± 0.072µs126.61x
PolkaVM (64-bit, recompiler, async gas)177.937µs ± 0.067µs134.45x
PolkaVM (64-bit, recompiler, sync gas)180.046µs ± 0.044µs136.05x
PolkaVM (32-bit, recompiler)181.955µs ± 0.062µs137.49x
PolkaVM (32-bit, recompiler, async gas)192.550µs ± 0.026µs145.50x
PolkaVM (32-bit, recompiler, sync gas)194.093µs ± 0.094µs146.66x
Wasmi (lazy translation, checked)384.444µs ± 4.764µs290.49x
Solana RBPF840.474µs ± 0.414µs635.08x
Wasmi (eager, checked)894.722µs ± 5.846µs676.07x
wazero2.543ms ± 0.108ms1921.70x
Wasmer (singlepass)3.946ms ± 0.006ms2982.04x
Wasmtime (winch)16.569ms ± 0.087ms12519.78x
Wasmtime (cranelift)62.212ms ± 0.024ms47008.50x
Wasmtime (cranelift, epoch interruption)70.161ms ± 0.029ms53014.87x
Wasmtime (cranelift, fuel metering)83.551ms ± 0.053ms63133.33x

Benchmark: prime-sieve

This benchmark is a prime sieve, searching for subsequent prime numbers. (source code)

Oneshot execution (for prime-sieve)

These benchmarks measure the end-to-end time that it takes to run the program a single time, including compilation and initialization.

VMTimevs fastest
(bare metal)10.932ms ± 0.020ms1.00x
PolkaVM (64-bit, recompiler)14.390ms ± 0.031ms1.32x
PolkaVM (64-bit, recompiler, async gas)17.682ms ± 0.030ms1.62x
PolkaVM (32-bit, recompiler)19.469ms ± 0.061ms1.78x
PolkaVM (64-bit, recompiler, sync gas)26.057ms ± 0.089ms2.38x
PolkaVM (32-bit, recompiler, async gas)27.653ms ± 2.714ms2.53x
PolkaVM (32-bit, recompiler, sync gas)27.803ms ± 0.052ms2.54x
Wasmtime (winch)54.295ms ± 0.013ms4.97x
Wasmer (singlepass)57.379ms ± 0.046ms5.25x
Wasmtime (cranelift, epoch interruption)108.176ms ± 0.097ms9.90x
Wasmtime (cranelift)125.107ms ± 0.361ms11.44x
Wasmtime (cranelift, fuel metering)157.072ms ± 0.097ms14.37x
Wasm3238.356ms ± 1.702ms21.80x
CKB VM (ASM)289.706ms ± 0.570ms26.50x
Wasmi (lazy, checked)398.243ms ± 1.191ms36.43x
Wasmi (lazy translation, checked)399.351ms ± 0.858ms36.53x
Wasmi (eager, checked)399.988ms ± 0.821ms36.59x
Solana RBPF420.127ms ± 0.798ms38.43x
PolkaVM (64-bit, interpreter)602.392ms ± 1.195ms55.10x
PolkaVM (32-bit, interpreter)752.598ms ± 0.626ms68.84x
CKB VM (non-ASM)2.544 s ± 0.004s232.67x

Execution time (for prime-sieve)

These benchmarks measure the execution time of the benchmark, without the time it takes to compile or initialize it.

VMTimevs fastest
(bare metal)1.639ms ± 0.039ms1.00x
PolkaVM (64-bit, recompiler)2.104ms ± 0.005ms1.28x
Wasmtime (cranelift)2.161ms ± 0.005ms1.32x
PolkaVM (64-bit, recompiler, async gas)2.171ms ± 0.004ms1.33x
PolkaVM (64-bit, recompiler, sync gas)2.193ms ± 0.004ms1.34x
PolkaVM (32-bit, recompiler)2.403ms ± 0.005ms1.47x
Wasmtime (cranelift, epoch interruption)2.435ms ± 0.006ms1.49x
Wasmtime (cranelift, fuel metering)2.465ms ± 0.010ms1.50x
PolkaVM (32-bit, recompiler, async gas)2.467ms ± 0.006ms1.51x
PolkaVM (32-bit, recompiler, sync gas)2.482ms ± 0.004ms1.51x
Wasmtime (winch)5.081ms ± 0.004ms3.10x
Wasmer (singlepass)6.120ms ± 0.025ms3.73x
Wasm322.545ms ± 0.046ms13.76x
CKB VM (ASM)27.559ms ± 0.006ms16.82x
Wasmi (lazy, checked)46.514ms ± 0.024ms28.38x
Wasmi (lazy translation, checked)46.521ms ± 0.033ms28.39x
Wasmi (eager, checked)47.138ms ± 1.106ms28.76x
PolkaVM (64-bit, interpreter)75.746ms ± 0.033ms46.22x
PolkaVM (32-bit, interpreter)91.441ms ± 0.043ms55.80x
Solana RBPF166.772ms ± 0.511ms101.77x
CKB VM (non-ASM)374.649ms ± 0.691ms228.62x

Compilation time (for prime-sieve)

These benchmarks measure the time it takes to compile a given program by the VM.

VMTimevs fastest
PolkaVM (64-bit, interpreter)0.581µs ± 0.000µs1.00x
PolkaVM (32-bit, interpreter)0.582µs ± 0.000µs1.00x
Wasmi (lazy, checked)77.007µs ± 2.521µs132.53x
PolkaVM (32-bit, recompiler)434.055µs ± 0.191µs747.03x
PolkaVM (64-bit, recompiler)442.354µs ± 0.369µs761.31x
PolkaVM (32-bit, recompiler, async gas)456.789µs ± 0.204µs786.16x
PolkaVM (32-bit, recompiler, sync gas)464.064µs ± 0.187µs798.68x
PolkaVM (64-bit, recompiler, async gas)465.916µs ± 0.201µs801.86x
PolkaVM (64-bit, recompiler, sync gas)473.516µs ± 0.243µs814.94x
Wasmi (lazy translation, checked)598.222µs ± 2.895µs1029.57x
Wasmi (eager, checked)1.668ms ± 0.004ms2870.28x
Solana RBPF2.252ms ± 0.001ms3876.33x
wazero4.049ms ± 0.423ms6969.12x
Wasmtime (winch)8.510ms ± 0.004ms14645.59x
Wasmer (singlepass)9.421ms ± 0.016ms16213.84x
Wasmtime (cranelift)76.662ms ± 0.101ms131939.72x
Wasmtime (cranelift, epoch interruption)84.835ms ± 0.047ms146004.53x
Wasmtime (cranelift, fuel metering)130.264ms ± 0.052ms224191.07x

Benchmark: minimal

This benchmark is a tiny, minimal program which doesn't do much work; it just increments a global variable and returns immediately. It is a good test case for measuring constant-time overhead. (source code)

Oneshot execution (for minimal)

These benchmarks measure the end-to-end time that it takes to run the program a single time, including compilation and initialization.

VMTimevs fastest
PolkaVM (64-bit, interpreter)2.533µs ± 0.002µs1.00x
PolkaVM (32-bit, interpreter)2.563µs ± 0.006µs1.01x
CKB VM (non-ASM)7.198µs ± 0.006µs2.84x
Wasm323.486µs ± 0.034µs9.27x
Wasmi (lazy, checked)25.833µs ± 0.226µs10.20x
Wasmi (lazy translation, checked)26.224µs ± 0.321µs10.35x
Wasmi (eager, checked)27.169µs ± 0.442µs10.73x
Solana RBPF30.957µs ± 0.035µs12.22x
(bare metal)42.610µs ± 0.127µs16.82x
CKB VM (ASM)65.851µs ± 0.128µs26.00x
PolkaVM (32-bit, recompiler)113.521µs ± 0.339µs44.82x
PolkaVM (64-bit, recompiler, sync gas)113.633µs ± 0.367µs44.87x
PolkaVM (32-bit, recompiler, async gas)113.685µs ± 0.302µs44.89x
PolkaVM (64-bit, recompiler)113.743µs ± 0.298µs44.91x
PolkaVM (64-bit, recompiler, async gas)113.778µs ± 0.340µs44.92x
PolkaVM (32-bit, recompiler, sync gas)113.916µs ± 0.280µs44.98x
Wasmer (singlepass)128.467µs ± 1.983µs50.72x
Wasmtime (winch)644.160µs ± 1.746µs254.34x
Wasmtime (cranelift)935.241µs ± 2.305µs369.27x
Wasmtime (cranelift, epoch interruption)1.089ms ± 0.001ms430.12x
Wasmtime (cranelift, fuel metering)1.144ms ± 0.001ms451.51x

Execution time (for minimal)

These benchmarks measure the execution time of the benchmark, without the time it takes to compile or initialize it.

VMTimevs fastest
(bare metal)0.050µs ± 0.003µs1.00x
Wasmer (singlepass)0.139µs ± 0.002µs2.79x
Wasm30.144µs ± 0.001µs2.90x
Wasmi (lazy translation, checked)0.151µs ± 0.000µs3.03x
Wasmi (lazy, checked)0.152µs ± 0.000µs3.05x
Wasmi (eager, checked)0.154µs ± 0.000µs3.09x
Solana RBPF0.167µs ± 0.000µs3.35x
PolkaVM (32-bit, interpreter)0.203µs ± 0.000µs4.07x
PolkaVM (64-bit, interpreter)0.203µs ± 0.000µs4.07x
Wasmtime (cranelift, epoch interruption)0.247µs ± 0.004µs4.96x
Wasmtime (winch)0.249µs ± 0.003µs4.99x
Wasmtime (cranelift, fuel metering)0.250µs ± 0.003µs5.02x
Wasmtime (cranelift)0.252µs ± 0.006µs5.06x
CKB VM (ASM)2.708µs ± 0.002µs54.35x
CKB VM (non-ASM)3.501µs ± 0.001µs70.28x
PolkaVM (64-bit, recompiler)4.852µs ± 0.040µs97.39x
PolkaVM (32-bit, recompiler, async gas)4.893µs ± 0.049µs98.21x
PolkaVM (32-bit, recompiler)4.918µs ± 0.034µs98.72x
PolkaVM (64-bit, recompiler, sync gas)4.929µs ± 0.024µs98.94x
PolkaVM (64-bit, recompiler, async gas)4.937µs ± 0.031µs99.09x
PolkaVM (32-bit, recompiler, sync gas)4.943µs ± 0.046µs99.22x

Compilation time (for minimal)

These benchmarks measure the time it takes to compile a given program by the VM.

VMTimevs fastest
PolkaVM (64-bit, interpreter)0.589µs ± 0.001µs1.00x
PolkaVM (32-bit, interpreter)0.599µs ± 0.001µs1.02x
PolkaVM (32-bit, recompiler)1.810µs ± 0.001µs3.07x
PolkaVM (64-bit, recompiler)1.823µs ± 0.002µs3.09x
PolkaVM (32-bit, recompiler, async gas)1.830µs ± 0.001µs3.11x
PolkaVM (64-bit, recompiler, async gas)1.832µs ± 0.001µs3.11x
PolkaVM (64-bit, recompiler, sync gas)1.852µs ± 0.002µs3.14x
PolkaVM (32-bit, recompiler, sync gas)1.854µs ± 0.002µs3.15x
Wasmi (lazy, checked)5.734µs ± 0.074µs9.73x
Wasmi (lazy translation, checked)6.572µs ± 0.112µs11.15x
Wasmi (eager, checked)8.331µs ± 0.020µs14.14x
Solana RBPF25.867µs ± 0.034µs43.90x
Wasmer (singlepass)85.955µs ± 5.566µs145.87x
wazero197.802µs ± 0.387µs335.69x
Wasmtime (winch)575.089µs ± 2.634µs975.98x
Wasmtime (cranelift)858.096µs ± 9.056µs1456.27x
Wasmtime (cranelift, epoch interruption)1.021ms ± 0.004ms1732.84x
Wasmtime (cranelift, fuel metering)1.068ms ± 0.010ms1812.18x

Supplemental information

CPU: AMD Ryzen Threadripper 3970X 32-Core Processor

Platform: x86_64-linux

Commit: 190ea5ac10344714b914230974bb9cb12bef56d6

Timestamp: 2024-11-24 03:45:40 UTC


Replication

You can replicate these benchmarks as follows:

$ git clone https://github.com/koute/polkavm.git
$ cd polkavm
$ git checkout 190ea5ac10344714b914230974bb9cb12bef56d6
$ cd tools/benchtool
$ ./01-build-benchmarks.sh
$ ./02-run-benchmarks.rb
$ ./03-analyze-benchmarks.rb

Only running the benchmarks on Linux is officially supported.

WARNING: The 02-run-benchmarks.rb script uses a couple of system-level tricks to make benchmarking more consistent and requires 'sudo' and 'schedtool' to be installed. If you're uncomfortable with that or if you're running a non-Linux OS you can also run the benchmarks with cargo run --release instead.