open-standards/wai/research/determinism-cost.md
Transaction Science 61759c51b5 wai: the int_hyper decode on the narrow kernel sets, measured; determinism-tiers §7 quotes it
research/determinism-cost.md §4.6, in the same record and by the same
procedure: the 192 payloads decoded again on every platform with every
kernel set it runs (15 new runs, 0 decodes differing from the record's),
and the record's time and energy runs repeated in one session per host
beside the record's own build and the float decoder. On x86_64 host A the
integer decode on the narrow kernels took 144.8 ms and 12.43 J of marginal
package energy at quality 6 against 210.7 ms and 14.03 J for the float
decode beside it (the record's build: 728.0 ms, 92.14 J). On the build
host its own CPU energy fell from 11.01 J to 6.43 J at quality 6 and is
still above the float decode's 1.28 J by that count. Host B's integer
decode was measured before and after, without a float decode beside it.
The scripts that took the readings are in runs/; decode-throughput.md
notes the new sets; the changelog records the change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 04:06:15 -04:00

452 lines
67 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# What exactness costs: `wai.neural.int_hyper` against its float model
> **Status.** A measured record and its procedure, informative. Every figure below is
> computed from the readings in [`determinism-cost/record.json`](determinism-cost/record.json),
> and `tools/wai_determinism_cost_verify.py` recomputes each one from those readings and
> checks every figure this page and [determinism-tiers](../extensions/determinism-tiers.md)
> §7 quote from it (each is followed by a `det` marker naming its place in the record).
> What WAI claims, and does not, on the strength of this record is in determinism-tiers §7.
> Measured 2026-10-22; the runs of §4.6, on the narrow kernel sets, 2026-10-24 and 2026-10-25.
## 1. What is measured, and what is not
`wai.neural.int_hyper` is an integer export of one pretrained learned codec: the
mean-scale hyperprior `mbt2018_mean` (MSE), quantised to per-channel 12-bit weights and
activations at 2¹², with an integer inverse GDN and an integer hyper-decoder that decides
every entropy table (determinism-tiers §5). The float model is the same checkpoint, coded
and decoded by the library its checkpoints are published with. This record measures what
the integer decode costs against that float model, at all eight published qualities, on
pictures of the pinned reference set:
1. **Rate and distortion**: the BD-rate of the integer codec against the float codec, by
PSNR and by MS-SSIM (§2.4).
2. **Reproducibility across platforms**: each codec's streams decoded on every platform
reached, and each decode compared byte for byte with the first platform's (§2.5).
3. **Time and energy** of a decode, both codecs, on the CPU and on a GPU (§2.6).
Not measured here, and why:
- **`wai.image.jpegai`'s exact decoder.** It implements one configuration of the base
standard, which gives one rate point per picture, so it has no rate-distortion curve to
take a BD-rate over; and coding the reference set needs the standard's reference
encoder, which was not run. Its one comparison with the reference decoder, on one
codestream, is determinism-tiers §5 and §6.
- **`wai.neural.int_synth` and `wai.neural.int_mlicpp`.** Neither has a float model with a
rate axis to compare with: the committed `int_synth` vectors are a synthesis from a
given latent (one of them a quantised float model trained on one photograph, the others
seeded integer weights), and the `int_mlicpp` vector has seeded weights.
- **`wai.neural.mbt2018_mean`**, WAI's float capability over the same model family, which
decodes through an ONNX runtime. The float side here is the model's own library.
- **A neural processor.** No decoder on main runs its graphs on one
(determinism-tiers §5).
- **The encoder.** Both codecs analyse the picture in floating point. The integer tier
covers the decode: the bytes of a payload depend on the machine that encoded it, and
every conforming sink then decodes those bytes to the same picture.
## 2. Procedure
### 2.1 Pictures
The pinned reference manifest `wai-image-references.json` (SHA-256 `db33c663…6b554b66`,
the manifest `tools/wai_visual_provenance_check.py` pins) lists 384 files. The rule:
every PNG entry the manifest marks `self_test` that holds one picture of 768×512 or
512×768 samples. That gives 24 pictures, each checked against the manifest's SHA-256
before it is read and named in the record by the first 16 hex digits of that digest.
Both sides are multiples of 64, so every picture is coded whole.
### 2.2 The two codecs
- **Checkpoints.** The eight published `mbt2018_mean` (MSE) checkpoints, qualities 1–8,
each pinned by the SHA-256 of its bytes (`CKPT_SHA256` in
`tools/wai_determinism_cost.py`, and in the record) and loaded as tensors only.
Qualities 1–4 have N = 128, M = 192; qualities 5–8, N = 192, M = 320.
- **Float codec.** The library's own `compress` and `decompress` (release 1.2.8, on the
pinned stack of `tools/requirements-sota-int.txt`): the float analysis, the factorised
hyper-latent, the float hyper-decoder deciding each scale bucket, the float synthesis.
Its reconstruction in [0, 1] becomes 8-bit samples by ×255 and rounding half to even.
- **Integer codec.** The same model exported per quality exactly as
`tools/wai_sota_int_synth_export.py` exports quality 6, coded as a `WIH1` payload
(integer-payloads §4), and decoded by `wai_det_cost`, which runs `int_payload::decode_int`,
the integer decode path every reference sink runs. Two cross-checks tie the export to
the one CI already checks, both run on the build host: the quality-6 set this procedure
writes (`g_s.whm`, `h_s.whm`, `entropy.json`) is byte for byte the set the export tool
writes; and on the export tool's pinned photograph (from `tools/wai_sota_source_image.py`),
this procedure's integer encoder gives the export tool's hyper-decoder output and writes
both rANS streams byte for byte as the export tool does.
- **Encoding.** The library on one CPU thread with deterministic algorithms, on the build
host (§3).
### 2.3 Rate and distortion
- **Rate**: the bytes of the two entropy-coded streams, hyper-latent and latent, for both
codecs, ×8 over the picture's samples per channel (bits per pixel). A `WIH1` payload adds
a 32-byte header and two 4-byte lengths, which are not counted; the record keeps each
payload's size.
- **PSNR**: 10·log₁₀(255²·n / SSE) over all n samples of the three channels, against the
picture's 8-bit samples.
- **MS-SSIM**, the perceptual metric: per channel on 8-bit samples (dynamic range 255),
five scales, an 11-tap Gaussian window of σ = 1.5 applied over the valid region,
K₁ = 0.01, K₂ = 0.03, 2×2 mean pooling between scales, the contrast-structure term at
the first four scales and luminance-contrast-structure at the fifth, exponents 0.0448,
0.2856, 0.3001, 0.2363 and 0.1333, each term clamped at zero; the mean over the three
channels. BD-rate reads it as −10·log₁₀(1 − MS-SSIM).
### 2.4 BD-rate
Per picture, the integer codec's eight (rate, quality) points against the float codec's
eight, by the Bjøntegaard delta of ITU-T VCEG-M33: log₁₀ of the rate interpolated as a
function of quality by a monotone piecewise-cubic Hermite interpolant (the
Fritsch–Carlson slopes with the three-point shape-preserving ends), each curve integrated
over the quality range the two share, and the mean difference in log rate turned into a
percentage. A positive figure is the extra rate the integer codec needs for the float
codec's quality. A curve whose quality does not rise strictly with rate has no BD-rate, and
the record lists such pictures. The record states each picture's figure, and their
median, mean, minimum and maximum.
### 2.5 Reproducibility across platforms
Every integer payload is decoded on each platform of §3, and each decode's RGB8 compared
by SHA-256 with the build host's first decode of it. Every float stream is decoded again
in a fresh process on each platform and device of §3, under the entropy tables the
encoder used (their SHA-256 is recorded per platform, so a difference in the tables would
show), and its RGB8, its decoded entropy-table indexes and its decoded symbols compared,
each by SHA-256, with the encoding process's own decode. A decode whose indexes or symbols
differ has diverged in the entropy decode; one whose symbols agree and whose samples
differ has diverged after it. For every float decode that differs, the record keeps its
PSNR change.
### 2.6 Time and energy
`tools/wai_det_energy.py` runs a decoder as a child process that loads its models and
streams, decodes each once, and then decodes the same eight pictures (the first eight of
§2.1, at quality 2 and at quality 6) in each of seven rounds on command, blocking between
rounds. A round's time is the child's own clock around its decodes; every decode's output is
hashed and compared with its first decode, so no time is reported for a different output.
The counters, each with its scope:
- **The decoder's own CPU energy** (macOS): the kernel's per-task energy count
(`ri_energy_nj`, `proc_pid_rusage`), read while the child blocks and only once its CPU
time has stopped moving, so every thread's energy has folded into the count. Scope: the
decoding process, CPU only; it excludes the GPU. Class `OnChipCounter`, filtering
unknown. Energy that system services spend on the process's behalf is billed to it in a
separate count, which the record keeps beside it.
- **The GPU rail** (macOS): IOReport's `GPU Energy` channel, the whole GPU, read every
100 ms. A round's GPU figure counts only where the decoder held at least 99% of the GPU
time that every accelerator client accumulated over the round (the I/O Registry's
`accumulatedGPUTime`), which the record keeps per round.
- **Package energy** (Linux): powercap `package-0`, the whole package, read every 100 ms.
A whole-device counter is bracketed by 5 s idle windows before and after every round. A
round's marginal energy is the counter's advance over the round minus the mean idle power
of its two brackets times the round's span, and its ratio is the marginal power over the
larger idle standard deviation (energy-measurement §3, §4). A round's figure is used only
where the counter was live in the round and in both its brackets (energy-measurement §3.1:
advancing in two intervals in a row, in five or more and in at least four of every five,
over at least 300 ms) and its ratio is at least 3; a figure is publishable only where all
seven rounds are used and read clean (ratio ≥ 10). The record
gives every round's readings, and per run the median, minimum and maximum over rounds of
the time and of each energy figure per decode, with the host's load average.
## 3. Platforms
| platform | machine | what ran |
|---|---|---|
| build host | arm64 desktop SoC, 24 performance and 8 efficiency cores, 80-core integrated GPU; macOS 27.0.1; shared, under heavy load from other work | both encoders; the integer decode on the CPU (all cores, one core), on the GPU (Metal) and as wasm32-wasip2 under wasmtime 49.0.3; the float decode on the CPU (one thread, the library's default of 24) and on the GPU (Metal); the timed runs with the per-task count and the GPU rail |
| x86_64 host A | x86_64 SoC, 16 cores and 32 threads, AVX-512, integrated GPU of PCI vendor 0x1002 (device 0x1586); Linux 7.0, glibc 2.43; shared, otherwise lightly loaded | the integer decode on the CPU, on the GPU (Vulkan, Mesa 26.0.8) and as the build host's wasm32-wasip2 binary under wasmtime 49.0.3; the float decode on the CPU (one thread, the library's default of 16); the timed runs with the package counter |
| x86_64 host B | x86_64 laptop CPU, 14 cores and 20 threads, AVX2, discrete GPU of PCI vendor 0x10de (device 0x28e1); Linux 7.0, glibc 2.39 | the integer decode on the CPU and on the GPU (Vulkan, driver 595.84); the float decode on the CPU (the library's default of 14 threads) and on the GPU (through the GPU vendor's compute API, in the float stack's 2.14.0 build for it) |
Builds: rustc 1.98.0, release profile, `--no-default-features --features neural_int`
(with `ops_gpu` for the GPU decodes, wgpu 30.0.1); the wasm32-wasip2 binary was built once,
on the build host, and the same file ran on both hosts. Float stack: Python 3.11 (3.12 on
host B), the pinned versions of `tools/requirements-sota-int.txt` (its CPU-only build on
host A, its GPU build on host B), with deterministic algorithms requested. The tags under which the record
keeps each platform are in `determinism-cost/runs/README.md`.
§4.6's builds are the same, from the change that added the narrow kernel sets, made on each
host (the wasm32-wasip2 file again once, on the build host), beside each host's build of the
record's own commit; on host A the float stack was set up again from the same pinned
versions. Host B's GPU was not reached for §4.6 (its driver was not loaded when the runs
were taken), so its GPU decode is the record's only.
## 4. Results
Every figure here is the record's, and the verifier of §6 recomputes it; each is followed by a marker naming
its place in `record.json`, and `wai_determinism_cost_verify.py` holds the text to the
record.
In brief:
- **Rate.** At equal PSNR the integer codec needs a median of
+1.61 %<!--det:summary.bd_rate_percent.psnr.median--> more rate than the float codec over
the 24 pictures, and at equal MS-SSIM a median of
+0.95 %<!--det:summary.bd_rate_percent.ms_ssim.median-->. The smallest figure of any
picture is +0.56 %<!--det:summary.bd_rate_percent.psnr.min--> by PSNR and
+0.52 %<!--det:summary.bd_rate_percent.ms_ssim.min--> by MS-SSIM: the export costs rate on
every picture (§4.1, and each picture's figure in the record).
- **Bytes.** The integer decode gave the same bytes on every platform, under every kernel
set: 0<!--det:summary.integer_cross_platform_total.differ--> of
4608<!--det:summary.integer_cross_platform_total.decodes--> decodes differed (§4.3, §4.6). The
float decode gave the encoder's bytes only on the encoder's own CPU. Everywhere else it
gave other bytes for every stream, and its entropy decode diverged on many of them, from
76<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.symbols_differ--> of 192 on host
B's CPU to 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.symbols_differ--> on
its GPU (§4.4).
- **Time and energy.** On host A, where every round read clean, the record's integer
decode took longer and drew more package energy than the float decode on the same CPU, at
both qualities, and so did the integer decode with its graphs on the integrated GPU
(§4.5). On the narrow kernel sets (§4.6) the same integer decode, giving the same bytes,
took 144.8<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.median--> ms and
12.43<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> J at quality 6
against 210.7<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.median--> ms and
14.03<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.median--> J for the float
decode measured beside it, and less time and energy than the float decode at quality 2
as well. On the build host it still drew more of its own CPU energy than the float decode
(§4.6, and §5 on what that count covers there).
### 4.1 BD-rate, integer codec against float codec
| quality metric | pictures | median | mean | min | max |
|---|---:|---:|---:|---:|---:|
| PSNR | 24<!--det:summary.bd_rate_percent.psnr.n--> | +1.61<!--det:summary.bd_rate_percent.psnr.median--> % | +1.71<!--det:summary.bd_rate_percent.psnr.mean--> % | +0.56<!--det:summary.bd_rate_percent.psnr.min--> % | +2.97<!--det:summary.bd_rate_percent.psnr.max--> % |
| MS-SSIM | 24<!--det:summary.bd_rate_percent.ms_ssim.n--> | +0.95<!--det:summary.bd_rate_percent.ms_ssim.median--> % | +1.03<!--det:summary.bd_rate_percent.ms_ssim.mean--> % | +0.52<!--det:summary.bd_rate_percent.ms_ssim.min--> % | +2.45<!--det:summary.bd_rate_percent.ms_ssim.max--> % |
### 4.2 Per quality (medians over the pictures)
| quality | float bpp | float PSNR (dB) | integer rate ÷ float rate | ΔPSNR (dB), integer − float | ΔMS-SSIM (dB), integer − float |
|---:|---:|---:|---:|---:|---:|
| 1 | 0.106<!--det:summary.per_quality.q1.float_bpp.median--> | 28.16<!--det:summary.per_quality.q1.float_psnr_db.median--> | 1.0006<!--det:summary.per_quality.q1.rate_ratio.median--> | -0.005<!--det:summary.per_quality.q1.delta_psnr_db.median--> | -0.005<!--det:summary.per_quality.q1.delta_ms_ssim_db.median--> |
| 2 | 0.166<!--det:summary.per_quality.q2.float_bpp.median--> | 29.74<!--det:summary.per_quality.q2.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q2.rate_ratio.median--> | -0.007<!--det:summary.per_quality.q2.delta_psnr_db.median--> | -0.007<!--det:summary.per_quality.q2.delta_ms_ssim_db.median--> |
| 3 | 0.248<!--det:summary.per_quality.q3.float_bpp.median--> | 31.36<!--det:summary.per_quality.q3.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q3.rate_ratio.median--> | -0.016<!--det:summary.per_quality.q3.delta_psnr_db.median--> | -0.010<!--det:summary.per_quality.q3.delta_ms_ssim_db.median--> |
| 4 | 0.370<!--det:summary.per_quality.q4.float_bpp.median--> | 32.99<!--det:summary.per_quality.q4.float_psnr_db.median--> | 1.0001<!--det:summary.per_quality.q4.rate_ratio.median--> | -0.032<!--det:summary.per_quality.q4.delta_psnr_db.median--> | -0.018<!--det:summary.per_quality.q4.delta_ms_ssim_db.median--> |
| 5 | 0.550<!--det:summary.per_quality.q5.float_bpp.median--> | 34.78<!--det:summary.per_quality.q5.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q5.rate_ratio.median--> | -0.022<!--det:summary.per_quality.q5.delta_psnr_db.median--> | -0.010<!--det:summary.per_quality.q5.delta_ms_ssim_db.median--> |
| 6 | 0.792<!--det:summary.per_quality.q6.float_bpp.median--> | 36.79<!--det:summary.per_quality.q6.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q6.rate_ratio.median--> | -0.174<!--det:summary.per_quality.q6.delta_psnr_db.median--> | -0.073<!--det:summary.per_quality.q6.delta_ms_ssim_db.median--> |
| 7 | 1.106<!--det:summary.per_quality.q7.float_bpp.median--> | 38.79<!--det:summary.per_quality.q7.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q7.rate_ratio.median--> | -0.176<!--det:summary.per_quality.q7.delta_psnr_db.median--> | -0.108<!--det:summary.per_quality.q7.delta_ms_ssim_db.median--> |
| 8 | 1.511<!--det:summary.per_quality.q8.float_bpp.median--> | 40.78<!--det:summary.per_quality.q8.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q8.rate_ratio.median--> | -0.942<!--det:summary.per_quality.q8.delta_psnr_db.median--> | -0.481<!--det:summary.per_quality.q8.delta_ms_ssim_db.median--> |
### 4.3 The integer decode across platforms
Tags (§3): `macos-arm64-cpu` the build host's CPU, all cores, and `-1t` one core; `macos-arm64-gpu-metal` its GPU; `wasm32-wasip2` the WebAssembly build under wasmtime there, and `wasm32-wasip2-x86_64` the same file on host A; `linux-x86_64-cpu` and `linux-x86_64-gpu-vulkan` host A's CPU and integrated GPU; `linux-x86_64-b-cpu` and `linux-x86_64-b-gpu-vulkan` host B's CPU and discrete GPU. Each line's decodes are the 192 payloads, 24 pictures at 8 qualities.
| platform | decodes | identical to the build host's CPU decode | differ | refused |
|---|---:|---:|---:|---:|
| `linux-x86_64-b-cpu` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu.refused--> |
| `linux-x86_64-b-gpu-vulkan` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-gpu-vulkan.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-gpu-vulkan.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-gpu-vulkan.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-gpu-vulkan.refused--> |
| `linux-x86_64-cpu` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu.refused--> |
| `linux-x86_64-gpu-vulkan` | 192<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan.refused--> |
| `macos-arm64-cpu` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu.refused--> |
| `macos-arm64-cpu-1t` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t.refused--> |
| `macos-arm64-gpu-metal` | 192<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal.refused--> |
| `wasm32-wasip2` | 192<!--det:summary.integer_cross_platform.wasm32-wasip2.decodes--> | 192<!--det:summary.integer_cross_platform.wasm32-wasip2.identical--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2.differ--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2.refused--> |
| `wasm32-wasip2-x86_64` | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64.decodes--> | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64.identical--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64.differ--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64.refused--> |
### 4.4 The float decode across platforms
Against the encoding process's own decode. Tags: `macos-arm64-cpu-1t` and `macos-arm64-cpu` the build host's CPU with one thread and with the library's default of 24, each in a fresh process; `macos-arm64-gpu-mps` its GPU; `linux-x86_64-cpu` and `linux-x86_64-cpu-1t` host A's CPU with the library's default of 16 threads and with one; `linux-x86_64-b-cpu` host B's CPU (14 threads); `linux-x86_64-b-cuda` host B's GPU. Where the symbols differ, the entropy decode diverged.
| platform | decodes | identical to the encoder's decode | differ | of which the indexes differ | of which the symbols differ | ΔPSNR where they differ (dB): median, min, max | ΔPSNR where the symbols differ (dB): median |
|---|---:|---:|---:|---:|---:|---|---:|
| `linux-x86_64-b-cpu` | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.decodes--> | 0<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.identical--> | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.rgb_differ--> | 76<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.indexes_differ--> | 76<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.symbols_differ--> | -0.000<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.delta_psnr_db_where_differ.median-->, -30.126<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.delta_psnr_db_where_differ.min-->, +0.000<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.delta_psnr_db_where_differ.max--> | -17.582<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.delta_psnr_db_where_symbols_differ.median--> |
| `linux-x86_64-b-cuda` | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.decodes--> | 0<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.identical--> | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.rgb_differ--> | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.indexes_differ--> | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.symbols_differ--> | -19.697<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.delta_psnr_db_where_differ.median-->, -30.518<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.delta_psnr_db_where_differ.min-->, -9.500<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.delta_psnr_db_where_differ.max--> | -19.697<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.delta_psnr_db_where_symbols_differ.median--> |
| `linux-x86_64-cpu` | 192<!--det:summary.float_cross_platform.linux-x86_64-cpu.decodes--> | 0<!--det:summary.float_cross_platform.linux-x86_64-cpu.identical--> | 192<!--det:summary.float_cross_platform.linux-x86_64-cpu.rgb_differ--> | 183<!--det:summary.float_cross_platform.linux-x86_64-cpu.indexes_differ--> | 183<!--det:summary.float_cross_platform.linux-x86_64-cpu.symbols_differ--> | -17.037<!--det:summary.float_cross_platform.linux-x86_64-cpu.delta_psnr_db_where_differ.median-->, -30.686<!--det:summary.float_cross_platform.linux-x86_64-cpu.delta_psnr_db_where_differ.min-->, +0.000<!--det:summary.float_cross_platform.linux-x86_64-cpu.delta_psnr_db_where_differ.max--> | -17.434<!--det:summary.float_cross_platform.linux-x86_64-cpu.delta_psnr_db_where_symbols_differ.median--> |
| `linux-x86_64-cpu-1t` | 192<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.decodes--> | 0<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.identical--> | 192<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.rgb_differ--> | 182<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.indexes_differ--> | 182<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.symbols_differ--> | -17.037<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.delta_psnr_db_where_differ.median-->, -30.457<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.delta_psnr_db_where_differ.min-->, +0.000<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.delta_psnr_db_where_differ.max--> | -17.345<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.delta_psnr_db_where_symbols_differ.median--> |
| `macos-arm64-cpu` | 192<!--det:summary.float_cross_platform.macos-arm64-cpu.decodes--> | 192<!--det:summary.float_cross_platform.macos-arm64-cpu.identical--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu.rgb_differ--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu.indexes_differ--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu.symbols_differ--> | — | — |
| `macos-arm64-cpu-1t` | 192<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.decodes--> | 192<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.identical--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.rgb_differ--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.indexes_differ--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.symbols_differ--> | — | — |
| `macos-arm64-gpu-mps` | 192<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.decodes--> | 0<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.identical--> | 192<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.rgb_differ--> | 184<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.indexes_differ--> | 184<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.symbols_differ--> | -17.200<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.delta_psnr_db_where_differ.median-->, -34.147<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.delta_psnr_db_where_differ.min-->, +0.000<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.delta_psnr_db_where_differ.max--> | -17.358<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.delta_psnr_db_where_symbols_differ.median--> |
### 4.5 Time and energy per decode (median over rounds; min–max)
Eight pictures per round, seven rounds; the runs' labels give the host (`linux` is host A, `macos` the build host), the codec, the fabric and the quality. The own CPU energy is the per-task count (macOS); the whole-device figure is the package counter (`rapl`, host A) or the GPU rail (`ioreport-gpu`, the build host), as the round's marginal over its idle brackets, from the rounds used (§2.6). The build host's rounds ran under the load average shown.
| run | time (ms) | own CPU energy (J) | whole-device marginal energy (J) | whole-device rounds | load average |
|---|---|---|---|---|---|
| `linux-float-cpu-q2` | 123.9<!--det:summary.timing.linux-float-cpu-q2.ms_per_decode.median--> (108.2<!--det:summary.timing.linux-float-cpu-q2.ms_per_decode.min-->–134.3<!--det:summary.timing.linux-float-cpu-q2.ms_per_decode.max-->) | — | rapl: 9.1<!--det:summary.timing.linux-float-cpu-q2.rapl.marginal_j_per_decode.median--> (8.0<!--det:summary.timing.linux-float-cpu-q2.rapl.marginal_j_per_decode.min-->–9.5<!--det:summary.timing.linux-float-cpu-q2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-float-cpu-q2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-float-cpu-q2.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-float-cpu-q2.load_avg_1min.min-->–3<!--det:summary.timing.linux-float-cpu-q2.load_avg_1min.max--> |
| `linux-float-cpu-q6` | 191.5<!--det:summary.timing.linux-float-cpu-q6.ms_per_decode.median--> (181.0<!--det:summary.timing.linux-float-cpu-q6.ms_per_decode.min-->–200.3<!--det:summary.timing.linux-float-cpu-q6.ms_per_decode.max-->) | — | rapl: 13.7<!--det:summary.timing.linux-float-cpu-q6.rapl.marginal_j_per_decode.median--> (13.3<!--det:summary.timing.linux-float-cpu-q6.rapl.marginal_j_per_decode.min-->–14.0<!--det:summary.timing.linux-float-cpu-q6.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-float-cpu-q6.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-float-cpu-q6.rapl.live_rounds--> live; 7 clean | 5<!--det:summary.timing.linux-float-cpu-q6.load_avg_1min.min-->–7<!--det:summary.timing.linux-float-cpu-q6.load_avg_1min.max--> |
| `linux-int-cpu-q2` | 347.3<!--det:summary.timing.linux-int-cpu-q2.ms_per_decode.median--> (346.4<!--det:summary.timing.linux-int-cpu-q2.ms_per_decode.min-->–348.6<!--det:summary.timing.linux-int-cpu-q2.ms_per_decode.max-->) | — | rapl: 42.4<!--det:summary.timing.linux-int-cpu-q2.rapl.marginal_j_per_decode.median--> (42.1<!--det:summary.timing.linux-int-cpu-q2.rapl.marginal_j_per_decode.min-->–42.5<!--det:summary.timing.linux-int-cpu-q2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q2.rapl.live_rounds--> live; 7 clean | 1<!--det:summary.timing.linux-int-cpu-q2.load_avg_1min.min-->–4<!--det:summary.timing.linux-int-cpu-q2.load_avg_1min.max--> |
| `linux-int-cpu-q6` | 729.6<!--det:summary.timing.linux-int-cpu-q6.ms_per_decode.median--> (728.7<!--det:summary.timing.linux-int-cpu-q6.ms_per_decode.min-->–731.6<!--det:summary.timing.linux-int-cpu-q6.ms_per_decode.max-->) | — | rapl: 92.5<!--det:summary.timing.linux-int-cpu-q6.rapl.marginal_j_per_decode.median--> (92.2<!--det:summary.timing.linux-int-cpu-q6.rapl.marginal_j_per_decode.min-->–92.7<!--det:summary.timing.linux-int-cpu-q6.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q6.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q6.rapl.live_rounds--> live; 7 clean | 3<!--det:summary.timing.linux-int-cpu-q6.load_avg_1min.min-->–11<!--det:summary.timing.linux-int-cpu-q6.load_avg_1min.max--> |
| `linux-int-gpu-q2` | 378.5<!--det:summary.timing.linux-int-gpu-q2.ms_per_decode.median--> (377.2<!--det:summary.timing.linux-int-gpu-q2.ms_per_decode.min-->–379.7<!--det:summary.timing.linux-int-gpu-q2.ms_per_decode.max-->) | — | rapl: 41.9<!--det:summary.timing.linux-int-gpu-q2.rapl.marginal_j_per_decode.median--> (41.0<!--det:summary.timing.linux-int-gpu-q2.rapl.marginal_j_per_decode.min-->–43.4<!--det:summary.timing.linux-int-gpu-q2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-gpu-q2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-gpu-q2.rapl.live_rounds--> live; 7 clean | 1<!--det:summary.timing.linux-int-gpu-q2.load_avg_1min.min-->–3<!--det:summary.timing.linux-int-gpu-q2.load_avg_1min.max--> |
| `linux-int-gpu-q6` | 845.4<!--det:summary.timing.linux-int-gpu-q6.ms_per_decode.median--> (844.1<!--det:summary.timing.linux-int-gpu-q6.ms_per_decode.min-->–846.2<!--det:summary.timing.linux-int-gpu-q6.ms_per_decode.max-->) | — | rapl: 93.5<!--det:summary.timing.linux-int-gpu-q6.rapl.marginal_j_per_decode.median--> (91.7<!--det:summary.timing.linux-int-gpu-q6.rapl.marginal_j_per_decode.min-->–93.8<!--det:summary.timing.linux-int-gpu-q6.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-gpu-q6.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-gpu-q6.rapl.live_rounds--> live; 7 clean | 1<!--det:summary.timing.linux-int-gpu-q6.load_avg_1min.min-->–5<!--det:summary.timing.linux-int-gpu-q6.load_avg_1min.max--> |
| `macos-float-cpu-q2` | 714.2<!--det:summary.timing.macos-float-cpu-q2.ms_per_decode.median--> (209.0<!--det:summary.timing.macos-float-cpu-q2.ms_per_decode.min-->–5663.9<!--det:summary.timing.macos-float-cpu-q2.ms_per_decode.max-->) | 0.7<!--det:summary.timing.macos-float-cpu-q2.task_j_per_decode.median--> (0.7<!--det:summary.timing.macos-float-cpu-q2.task_j_per_decode.min-->–0.7<!--det:summary.timing.macos-float-cpu-q2.task_j_per_decode.max-->) | — | — | 45<!--det:summary.timing.macos-float-cpu-q2.load_avg_1min.min-->–199<!--det:summary.timing.macos-float-cpu-q2.load_avg_1min.max--> |
| `macos-float-cpu-q6` | 403.4<!--det:summary.timing.macos-float-cpu-q6.ms_per_decode.median--> (214.6<!--det:summary.timing.macos-float-cpu-q6.ms_per_decode.min-->–736.4<!--det:summary.timing.macos-float-cpu-q6.ms_per_decode.max-->) | 1.2<!--det:summary.timing.macos-float-cpu-q6.task_j_per_decode.median--> (1.1<!--det:summary.timing.macos-float-cpu-q6.task_j_per_decode.min-->–1.5<!--det:summary.timing.macos-float-cpu-q6.task_j_per_decode.max-->) | — | — | 85<!--det:summary.timing.macos-float-cpu-q6.load_avg_1min.min-->–126<!--det:summary.timing.macos-float-cpu-q6.load_avg_1min.max--> |
| `macos-float-gpu-q2` | 51.7<!--det:summary.timing.macos-float-gpu-q2.ms_per_decode.median--> (50.0<!--det:summary.timing.macos-float-gpu-q2.ms_per_decode.min-->–55.3<!--det:summary.timing.macos-float-gpu-q2.ms_per_decode.max-->) | 0.1<!--det:summary.timing.macos-float-gpu-q2.task_j_per_decode.median--> (0.1<!--det:summary.timing.macos-float-gpu-q2.task_j_per_decode.min-->–0.1<!--det:summary.timing.macos-float-gpu-q2.task_j_per_decode.max-->) | ioreport-gpu: none usable | 0<!--det:summary.timing.macos-float-gpu-q2.ioreport-gpu.usable_rounds--> of 7 used; 0<!--det:summary.timing.macos-float-gpu-q2.ioreport-gpu.live_rounds--> live; 2 clean, 5 no ratio; GPU share 1.000<!--det:summary.timing.macos-float-gpu-q2.ioreport-gpu.gpu_share.min-->–1.000<!--det:summary.timing.macos-float-gpu-q2.ioreport-gpu.gpu_share.max--> | 126<!--det:summary.timing.macos-float-gpu-q2.load_avg_1min.min-->–149<!--det:summary.timing.macos-float-gpu-q2.load_avg_1min.max--> |
| `macos-float-gpu-q6` | 66.4<!--det:summary.timing.macos-float-gpu-q6.ms_per_decode.median--> (60.0<!--det:summary.timing.macos-float-gpu-q6.ms_per_decode.min-->–77.8<!--det:summary.timing.macos-float-gpu-q6.ms_per_decode.max-->) | 0.2<!--det:summary.timing.macos-float-gpu-q6.task_j_per_decode.median--> (0.1<!--det:summary.timing.macos-float-gpu-q6.task_j_per_decode.min-->–0.2<!--det:summary.timing.macos-float-gpu-q6.task_j_per_decode.max-->) | ioreport-gpu: none usable | 0<!--det:summary.timing.macos-float-gpu-q6.ioreport-gpu.usable_rounds--> of 7 used; 0<!--det:summary.timing.macos-float-gpu-q6.ioreport-gpu.live_rounds--> live; 4 no ratio, 3 clean; GPU share 0.113<!--det:summary.timing.macos-float-gpu-q6.ioreport-gpu.gpu_share.min-->–1.000<!--det:summary.timing.macos-float-gpu-q6.ioreport-gpu.gpu_share.max--> | 74<!--det:summary.timing.macos-float-gpu-q6.load_avg_1min.min-->–81<!--det:summary.timing.macos-float-gpu-q6.load_avg_1min.max--> |
| `macos-int-cpu-q2` | 152.4<!--det:summary.timing.macos-int-cpu-q2.ms_per_decode.median--> (115.1<!--det:summary.timing.macos-int-cpu-q2.ms_per_decode.min-->–376.8<!--det:summary.timing.macos-int-cpu-q2.ms_per_decode.max-->) | 4.6<!--det:summary.timing.macos-int-cpu-q2.task_j_per_decode.median--> (4.4<!--det:summary.timing.macos-int-cpu-q2.task_j_per_decode.min-->–4.8<!--det:summary.timing.macos-int-cpu-q2.task_j_per_decode.max-->) | — | — | 44<!--det:summary.timing.macos-int-cpu-q2.load_avg_1min.min-->–57<!--det:summary.timing.macos-int-cpu-q2.load_avg_1min.max--> |
| `macos-int-cpu-q6` | 648.9<!--det:summary.timing.macos-int-cpu-q6.ms_per_decode.median--> (519.5<!--det:summary.timing.macos-int-cpu-q6.ms_per_decode.min-->–865.7<!--det:summary.timing.macos-int-cpu-q6.ms_per_decode.max-->) | 10.5<!--det:summary.timing.macos-int-cpu-q6.task_j_per_decode.median--> (10.2<!--det:summary.timing.macos-int-cpu-q6.task_j_per_decode.min-->–10.9<!--det:summary.timing.macos-int-cpu-q6.task_j_per_decode.max-->) | — | — | 113<!--det:summary.timing.macos-int-cpu-q6.load_avg_1min.min-->–130<!--det:summary.timing.macos-int-cpu-q6.load_avg_1min.max--> |
| `macos-int-gpu-q2` | 251.3<!--det:summary.timing.macos-int-gpu-q2.ms_per_decode.median--> (248.7<!--det:summary.timing.macos-int-gpu-q2.ms_per_decode.min-->–253.5<!--det:summary.timing.macos-int-gpu-q2.ms_per_decode.max-->) | 0.1<!--det:summary.timing.macos-int-gpu-q2.task_j_per_decode.median--> (0.1<!--det:summary.timing.macos-int-gpu-q2.task_j_per_decode.min-->–0.1<!--det:summary.timing.macos-int-gpu-q2.task_j_per_decode.max-->) | ioreport-gpu: none usable | 0<!--det:summary.timing.macos-int-gpu-q2.ioreport-gpu.usable_rounds--> of 7 used; 5<!--det:summary.timing.macos-int-gpu-q2.ioreport-gpu.live_rounds--> live; 7 clean; GPU share 0.788<!--det:summary.timing.macos-int-gpu-q2.ioreport-gpu.gpu_share.min-->–0.916<!--det:summary.timing.macos-int-gpu-q2.ioreport-gpu.gpu_share.max--> | 117<!--det:summary.timing.macos-int-gpu-q2.load_avg_1min.min-->–128<!--det:summary.timing.macos-int-gpu-q2.load_avg_1min.max--> |
| `macos-int-gpu-q6` | 529.9<!--det:summary.timing.macos-int-gpu-q6.ms_per_decode.median--> (527.9<!--det:summary.timing.macos-int-gpu-q6.ms_per_decode.min-->–546.0<!--det:summary.timing.macos-int-gpu-q6.ms_per_decode.max-->) | 0.1<!--det:summary.timing.macos-int-gpu-q6.task_j_per_decode.median--> (0.1<!--det:summary.timing.macos-int-gpu-q6.task_j_per_decode.min-->–0.1<!--det:summary.timing.macos-int-gpu-q6.task_j_per_decode.max-->) | ioreport-gpu: none usable | 0<!--det:summary.timing.macos-int-gpu-q6.ioreport-gpu.usable_rounds--> of 7 used; 0<!--det:summary.timing.macos-int-gpu-q6.ioreport-gpu.live_rounds--> live; 2 clean, 5 no ratio; GPU share 0.923<!--det:summary.timing.macos-int-gpu-q6.ioreport-gpu.gpu_share.min-->–1.000<!--det:summary.timing.macos-int-gpu-q6.ioreport-gpu.gpu_share.max--> | 37<!--det:summary.timing.macos-int-gpu-q6.load_avg_1min.min-->–68<!--det:summary.timing.macos-int-gpu-q6.load_avg_1min.max--> |
On the build host no GPU-rail figure is used. While the GPU idled between rounds its rail
did not advance at all, so the idle brackets around most rounds were not live (§2.6); and
in some rounds another client held more than 1% of the GPU's time (the table's GPU share). Those rounds' readings are
in the record, and nothing is drawn from them. The per-task counts there are the
decoding process's own CPU energy, which the load on the host changes less than it changes
the time, but does change; §5 states what they cover.
### 4.6 The integer decode on the narrow kernel sets
The record's integer decoder (§4.3, §4.5) ran the wide kernels of `wai-rs`'s `int_kernels`:
32×32→64-bit multiply-accumulates, NEON on arm64 and portable Rust elsewhere. The runs of
this section are of the build that added the narrow kernel sets (`int_kernels::Isa`):
convolutions on 16-bit operands with 32-bit partial sums in blocks bounded so that no value
leaves its type (NEON on arm64; AVX2, AVX2 with VNNI, AVX-512 and AVX-512 with VNNI on
x86_64), the inverse GDN's norms and outputs in SIMD lanes, and the element-wise operators
and the requantisation in 64-bit arithmetic where their values fit. Every operator still
gives the interpreter's integers (the `int_kernels` documentation states how, and the tests
it names hold each set to the interpreter); the set is chosen by the processor's features,
or by `WAI_INT_ISA`. The wasm32-wasip2 build has no narrow set and runs the wide kernels, as
`wide` names below, with the build's other changes.
**Bytes.** Every payload decoded again on each platform with each kernel set the platform
runs, against the record's build host CPU decode (the GPU decodes run both graphs on the
device and are unchanged by the kernel sets; the runs check it):
| platform | kernel set | decodes | identical to the build host's CPU decode | differ | refused |
|---|---|---:|---:|---:|---:|
| `linux-x86_64-b-cpu` | `avx2` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2.refused--> |
| `linux-x86_64-b-cpu` | `avx2-vnni` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2-vnni.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2-vnni.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2-vnni.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2-vnni.refused--> |
| `linux-x86_64-b-cpu` | `wide` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-wide.refused--> |
| `linux-x86_64-cpu` | `avx2` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2.refused--> |
| `linux-x86_64-cpu` | `avx2-vnni` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2-vnni.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2-vnni.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2-vnni.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2-vnni.refused--> |
| `linux-x86_64-cpu` | `avx512` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512.refused--> |
| `linux-x86_64-cpu` | `avx512-vnni` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512-vnni.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512-vnni.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512-vnni.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512-vnni.refused--> |
| `linux-x86_64-cpu` | `wide` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-wide.refused--> |
| `linux-x86_64-gpu-vulkan` | `avx512-vnni` | 192<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan-isa-avx512-vnni.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan-isa-avx512-vnni.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan-isa-avx512-vnni.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan-isa-avx512-vnni.refused--> |
| `macos-arm64-cpu-1t` | `neon` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t-isa-neon.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t-isa-neon.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t-isa-neon.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t-isa-neon.refused--> |
| `macos-arm64-cpu` | `neon` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-neon.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-neon.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-neon.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-neon.refused--> |
| `macos-arm64-cpu` | `wide` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-wide.refused--> |
| `macos-arm64-gpu-metal` | `neon` | 192<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal-isa-neon.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal-isa-neon.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal-isa-neon.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal-isa-neon.refused--> |
| `wasm32-wasip2` | `wide` | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-isa-wide.refused--> |
| `wasm32-wasip2-x86_64` | `wide` | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64-isa-wide.refused--> |
**Time and energy.** The procedure of §2.6, on the same eight pictures. On each host the
runs were taken in one session: `-before` the record's own build of the integer decoder run
again, `-after` this section's build (its kernel set chosen by the processor: AVX-512 with
VNNI on host A, AVX2 with VNNI on host B, NEON on the build host; `-after-avx2` the AVX2 set
on host A), `-again` the float decoder run again. `linux-b` is host B, measured only for the
integer decode (its float stack was not set up again), under the load of the CI jobs it
also serves.
| run | time (ms) | own CPU energy (J) | whole-device marginal energy (J) | whole-device rounds | load average |
|---|---|---|---|---|---|
| `linux-b-int-cpu-q2-after` | 170.2<!--det:summary.timing.linux-b-int-cpu-q2-after.ms_per_decode.median--> (168.9<!--det:summary.timing.linux-b-int-cpu-q2-after.ms_per_decode.min-->–203.6<!--det:summary.timing.linux-b-int-cpu-q2-after.ms_per_decode.max-->) | — | rapl: 11.56<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.marginal_j_per_decode.median--> (9.31<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.marginal_j_per_decode.min-->–11.91<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.live_rounds--> live; 2 relative-only, 5 clean | 5<!--det:summary.timing.linux-b-int-cpu-q2-after.load_avg_1min.min-->–6<!--det:summary.timing.linux-b-int-cpu-q2-after.load_avg_1min.max--> |
| `linux-b-int-cpu-q2-before` | 714.0<!--det:summary.timing.linux-b-int-cpu-q2-before.ms_per_decode.median--> (704.2<!--det:summary.timing.linux-b-int-cpu-q2-before.ms_per_decode.min-->–716.3<!--det:summary.timing.linux-b-int-cpu-q2-before.ms_per_decode.max-->) | — | rapl: 43.84<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.marginal_j_per_decode.median--> (42.71<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.marginal_j_per_decode.min-->–44.30<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-b-int-cpu-q2-before.load_avg_1min.min-->–9<!--det:summary.timing.linux-b-int-cpu-q2-before.load_avg_1min.max--> |
| `linux-b-int-cpu-q6-after` | 294.3<!--det:summary.timing.linux-b-int-cpu-q6-after.ms_per_decode.median--> (292.3<!--det:summary.timing.linux-b-int-cpu-q6-after.ms_per_decode.min-->–301.1<!--det:summary.timing.linux-b-int-cpu-q6-after.ms_per_decode.max-->) | — | rapl: 19.97<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> (18.83<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.marginal_j_per_decode.min-->–20.20<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.live_rounds--> live; 7 clean | 6<!--det:summary.timing.linux-b-int-cpu-q6-after.load_avg_1min.min-->–11<!--det:summary.timing.linux-b-int-cpu-q6-after.load_avg_1min.max--> |
| `linux-b-int-cpu-q6-before` | 1582.1<!--det:summary.timing.linux-b-int-cpu-q6-before.ms_per_decode.median--> (1555.6<!--det:summary.timing.linux-b-int-cpu-q6-before.ms_per_decode.min-->–1598.9<!--det:summary.timing.linux-b-int-cpu-q6-before.ms_per_decode.max-->) | — | rapl: 84.92<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.marginal_j_per_decode.median--> (83.95<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.marginal_j_per_decode.min-->–87.95<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.live_rounds--> live; 7 clean | 6<!--det:summary.timing.linux-b-int-cpu-q6-before.load_avg_1min.min-->–12<!--det:summary.timing.linux-b-int-cpu-q6-before.load_avg_1min.max--> |
| `linux-float-cpu-q2-again` | 132.2<!--det:summary.timing.linux-float-cpu-q2-again.ms_per_decode.median--> (123.2<!--det:summary.timing.linux-float-cpu-q2-again.ms_per_decode.min-->–139.7<!--det:summary.timing.linux-float-cpu-q2-again.ms_per_decode.max-->) | — | rapl: 9.26<!--det:summary.timing.linux-float-cpu-q2-again.rapl.marginal_j_per_decode.median--> (9.00<!--det:summary.timing.linux-float-cpu-q2-again.rapl.marginal_j_per_decode.min-->–9.33<!--det:summary.timing.linux-float-cpu-q2-again.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-float-cpu-q2-again.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-float-cpu-q2-again.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-float-cpu-q2-again.load_avg_1min.min-->–4<!--det:summary.timing.linux-float-cpu-q2-again.load_avg_1min.max--> |
| `linux-float-cpu-q6-again` | 210.7<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.median--> (200.8<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.min-->–226.1<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.max-->) | — | rapl: 14.03<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.median--> (13.65<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.min-->–14.41<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-float-cpu-q6-again.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-float-cpu-q6-again.rapl.live_rounds--> live; 7 clean | 6<!--det:summary.timing.linux-float-cpu-q6-again.load_avg_1min.min-->–8<!--det:summary.timing.linux-float-cpu-q6-again.load_avg_1min.max--> |
| `linux-int-cpu-q2-after` | 92.9<!--det:summary.timing.linux-int-cpu-q2-after.ms_per_decode.median--> (90.8<!--det:summary.timing.linux-int-cpu-q2-after.ms_per_decode.min-->–93.1<!--det:summary.timing.linux-int-cpu-q2-after.ms_per_decode.max-->) | — | rapl: 7.31<!--det:summary.timing.linux-int-cpu-q2-after.rapl.marginal_j_per_decode.median--> (7.29<!--det:summary.timing.linux-int-cpu-q2-after.rapl.marginal_j_per_decode.min-->–7.50<!--det:summary.timing.linux-int-cpu-q2-after.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q2-after.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q2-after.rapl.live_rounds--> live; 7 clean | 3<!--det:summary.timing.linux-int-cpu-q2-after.load_avg_1min.min-->–5<!--det:summary.timing.linux-int-cpu-q2-after.load_avg_1min.max--> |
| `linux-int-cpu-q2-after-avx2` | 101.6<!--det:summary.timing.linux-int-cpu-q2-after-avx2.ms_per_decode.median--> (101.3<!--det:summary.timing.linux-int-cpu-q2-after-avx2.ms_per_decode.min-->–103.0<!--det:summary.timing.linux-int-cpu-q2-after-avx2.ms_per_decode.max-->) | — | rapl: 9.27<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.marginal_j_per_decode.median--> (9.22<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.marginal_j_per_decode.min-->–9.35<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.live_rounds--> live; 7 clean | 3<!--det:summary.timing.linux-int-cpu-q2-after-avx2.load_avg_1min.min-->–5<!--det:summary.timing.linux-int-cpu-q2-after-avx2.load_avg_1min.max--> |
| `linux-int-cpu-q2-before` | 345.8<!--det:summary.timing.linux-int-cpu-q2-before.ms_per_decode.median--> (345.2<!--det:summary.timing.linux-int-cpu-q2-before.ms_per_decode.min-->–346.4<!--det:summary.timing.linux-int-cpu-q2-before.ms_per_decode.max-->) | — | rapl: 42.25<!--det:summary.timing.linux-int-cpu-q2-before.rapl.marginal_j_per_decode.median--> (42.17<!--det:summary.timing.linux-int-cpu-q2-before.rapl.marginal_j_per_decode.min-->–42.33<!--det:summary.timing.linux-int-cpu-q2-before.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q2-before.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q2-before.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-int-cpu-q2-before.load_avg_1min.min-->–5<!--det:summary.timing.linux-int-cpu-q2-before.load_avg_1min.max--> |
| `linux-int-cpu-q6-after` | 144.8<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.median--> (142.7<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.min-->–147.7<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.max-->) | — | rapl: 12.43<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> (12.28<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.min-->–12.58<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q6-after.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q6-after.rapl.live_rounds--> live; 7 clean | 8<!--det:summary.timing.linux-int-cpu-q6-after.load_avg_1min.min-->–11<!--det:summary.timing.linux-int-cpu-q6-after.load_avg_1min.max--> |
| `linux-int-cpu-q6-after-avx2` | 166.3<!--det:summary.timing.linux-int-cpu-q6-after-avx2.ms_per_decode.median--> (164.7<!--det:summary.timing.linux-int-cpu-q6-after-avx2.ms_per_decode.min-->–166.8<!--det:summary.timing.linux-int-cpu-q6-after-avx2.ms_per_decode.max-->) | — | rapl: 16.46<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.marginal_j_per_decode.median--> (16.36<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.marginal_j_per_decode.min-->–16.53<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-int-cpu-q6-after-avx2.load_avg_1min.min-->–4<!--det:summary.timing.linux-int-cpu-q6-after-avx2.load_avg_1min.max--> |
| `linux-int-cpu-q6-before` | 728.0<!--det:summary.timing.linux-int-cpu-q6-before.ms_per_decode.median--> (725.8<!--det:summary.timing.linux-int-cpu-q6-before.ms_per_decode.min-->–729.8<!--det:summary.timing.linux-int-cpu-q6-before.ms_per_decode.max-->) | — | rapl: 92.14<!--det:summary.timing.linux-int-cpu-q6-before.rapl.marginal_j_per_decode.median--> (91.96<!--det:summary.timing.linux-int-cpu-q6-before.rapl.marginal_j_per_decode.min-->–92.67<!--det:summary.timing.linux-int-cpu-q6-before.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q6-before.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q6-before.rapl.live_rounds--> live; 7 clean | 4<!--det:summary.timing.linux-int-cpu-q6-before.load_avg_1min.min-->–12<!--det:summary.timing.linux-int-cpu-q6-before.load_avg_1min.max--> |
| `macos-float-cpu-q2-again` | 212.5<!--det:summary.timing.macos-float-cpu-q2-again.ms_per_decode.median--> (140.4<!--det:summary.timing.macos-float-cpu-q2-again.ms_per_decode.min-->–330.5<!--det:summary.timing.macos-float-cpu-q2-again.ms_per_decode.max-->) | 0.92<!--det:summary.timing.macos-float-cpu-q2-again.task_j_per_decode.median--> (0.81<!--det:summary.timing.macos-float-cpu-q2-again.task_j_per_decode.min-->–1.07<!--det:summary.timing.macos-float-cpu-q2-again.task_j_per_decode.max-->) | — | — | 40<!--det:summary.timing.macos-float-cpu-q2-again.load_avg_1min.min-->–47<!--det:summary.timing.macos-float-cpu-q2-again.load_avg_1min.max--> |
| `macos-float-cpu-q6-again` | 271.3<!--det:summary.timing.macos-float-cpu-q6-again.ms_per_decode.median--> (215.7<!--det:summary.timing.macos-float-cpu-q6-again.ms_per_decode.min-->–598.7<!--det:summary.timing.macos-float-cpu-q6-again.ms_per_decode.max-->) | 1.28<!--det:summary.timing.macos-float-cpu-q6-again.task_j_per_decode.median--> (1.22<!--det:summary.timing.macos-float-cpu-q6-again.task_j_per_decode.min-->–1.51<!--det:summary.timing.macos-float-cpu-q6-again.task_j_per_decode.max-->) | — | — | 46<!--det:summary.timing.macos-float-cpu-q6-again.load_avg_1min.min-->–61<!--det:summary.timing.macos-float-cpu-q6-again.load_avg_1min.max--> |
| `macos-int-cpu-q2-after` | 274.1<!--det:summary.timing.macos-int-cpu-q2-after.ms_per_decode.median--> (98.3<!--det:summary.timing.macos-int-cpu-q2-after.ms_per_decode.min-->–385.0<!--det:summary.timing.macos-int-cpu-q2-after.ms_per_decode.max-->) | 2.96<!--det:summary.timing.macos-int-cpu-q2-after.task_j_per_decode.median--> (2.83<!--det:summary.timing.macos-int-cpu-q2-after.task_j_per_decode.min-->–3.12<!--det:summary.timing.macos-int-cpu-q2-after.task_j_per_decode.max-->) | — | — | 32<!--det:summary.timing.macos-int-cpu-q2-after.load_avg_1min.min-->–46<!--det:summary.timing.macos-int-cpu-q2-after.load_avg_1min.max--> |
| `macos-int-cpu-q2-before` | 130.9<!--det:summary.timing.macos-int-cpu-q2-before.ms_per_decode.median--> (106.2<!--det:summary.timing.macos-int-cpu-q2-before.ms_per_decode.min-->–338.3<!--det:summary.timing.macos-int-cpu-q2-before.ms_per_decode.max-->) | 4.76<!--det:summary.timing.macos-int-cpu-q2-before.task_j_per_decode.median--> (4.47<!--det:summary.timing.macos-int-cpu-q2-before.task_j_per_decode.min-->–4.90<!--det:summary.timing.macos-int-cpu-q2-before.task_j_per_decode.max-->) | — | — | 34<!--det:summary.timing.macos-int-cpu-q2-before.load_avg_1min.min-->–42<!--det:summary.timing.macos-int-cpu-q2-before.load_avg_1min.max--> |
| `macos-int-cpu-q6-after` | 477.5<!--det:summary.timing.macos-int-cpu-q6-after.ms_per_decode.median--> (392.1<!--det:summary.timing.macos-int-cpu-q6-after.ms_per_decode.min-->–909.3<!--det:summary.timing.macos-int-cpu-q6-after.ms_per_decode.max-->) | 6.43<!--det:summary.timing.macos-int-cpu-q6-after.task_j_per_decode.median--> (6.12<!--det:summary.timing.macos-int-cpu-q6-after.task_j_per_decode.min-->–6.63<!--det:summary.timing.macos-int-cpu-q6-after.task_j_per_decode.max-->) | — | — | 32<!--det:summary.timing.macos-int-cpu-q6-after.load_avg_1min.min-->–62<!--det:summary.timing.macos-int-cpu-q6-after.load_avg_1min.max--> |
| `macos-int-cpu-q6-before` | 268.1<!--det:summary.timing.macos-int-cpu-q6-before.ms_per_decode.median--> (228.4<!--det:summary.timing.macos-int-cpu-q6-before.ms_per_decode.min-->–409.0<!--det:summary.timing.macos-int-cpu-q6-before.ms_per_decode.max-->) | 11.01<!--det:summary.timing.macos-int-cpu-q6-before.task_j_per_decode.median--> (10.93<!--det:summary.timing.macos-int-cpu-q6-before.task_j_per_decode.min-->–11.16<!--det:summary.timing.macos-int-cpu-q6-before.task_j_per_decode.max-->) | — | — | 33<!--det:summary.timing.macos-int-cpu-q6-before.load_avg_1min.min-->–47<!--det:summary.timing.macos-int-cpu-q6-before.load_avg_1min.max--> |
On host A every round of every run read clean. At quality 6 the narrow kernels took the
integer decode from 728.0<!--det:summary.timing.linux-int-cpu-q6-before.ms_per_decode.median--> ms and
92.14<!--det:summary.timing.linux-int-cpu-q6-before.rapl.marginal_j_per_decode.median--> J to
144.8<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.median--> ms and
12.43<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> J, against
210.7<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.median--> ms and
14.03<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.median--> J for the float decode;
at quality 2 from 345.8<!--det:summary.timing.linux-int-cpu-q2-before.ms_per_decode.median--> ms and
42.25<!--det:summary.timing.linux-int-cpu-q2-before.rapl.marginal_j_per_decode.median--> J to
92.9<!--det:summary.timing.linux-int-cpu-q2-after.ms_per_decode.median--> ms and
7.31<!--det:summary.timing.linux-int-cpu-q2-after.rapl.marginal_j_per_decode.median--> J, against
132.2<!--det:summary.timing.linux-float-cpu-q2-again.ms_per_decode.median--> ms and
9.26<!--det:summary.timing.linux-float-cpu-q2-again.rapl.marginal_j_per_decode.median--> J. With the AVX2 set
on the same host the integer decode drew
9.27<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.marginal_j_per_decode.median--> J at quality 2 and
16.46<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.marginal_j_per_decode.median--> J at quality 6.
The record's own runs of 2026-10-22 (§4.5) and the `-before` runs agree within a few
tenths of a joule.
On host B, under the load of the CI jobs it serves, the integer decode went from
1582.1<!--det:summary.timing.linux-b-int-cpu-q6-before.ms_per_decode.median--> ms and
84.92<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.marginal_j_per_decode.median--> J to
294.3<!--det:summary.timing.linux-b-int-cpu-q6-after.ms_per_decode.median--> ms and
19.97<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> J at quality 6, and
from 714.0<!--det:summary.timing.linux-b-int-cpu-q2-before.ms_per_decode.median--> ms and
43.84<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.marginal_j_per_decode.median--> J to
170.2<!--det:summary.timing.linux-b-int-cpu-q2-after.ms_per_decode.median--> ms and
11.56<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.marginal_j_per_decode.median--> J at quality 2, where
two of the seven rounds were relative-only against their idle brackets and the rest clean. No float decode was measured
beside them there.
On the build host the narrow kernels lowered the decoder's own CPU energy from
11.01<!--det:summary.timing.macos-int-cpu-q6-before.task_j_per_decode.median--> J to
6.43<!--det:summary.timing.macos-int-cpu-q6-after.task_j_per_decode.median--> J at quality 6 and from
4.76<!--det:summary.timing.macos-int-cpu-q2-before.task_j_per_decode.median--> J to
2.96<!--det:summary.timing.macos-int-cpu-q2-after.task_j_per_decode.median--> J at quality 2. The float decode's
own CPU energy there was 1.28<!--det:summary.timing.macos-float-cpu-q6-again.task_j_per_decode.median--> J and
0.92<!--det:summary.timing.macos-float-cpu-q2-again.task_j_per_decode.median--> J: by that count the integer
decode still costs more on this host, and the count may leave out the float decode's matrix
unit (§5). The host was under heavy load from other work throughout (the load averages in
the table). Its times swing with that load from round to round and from run to run by more
than the kernels change them, so that a run's median time there says little: the `-after`
runs' medians lie above the `-before` runs' though their ranges overlap, while each run's
per-task counts stay within a few tenths of a joule of each other. The per-task count is the
build host's comparable figure.
## 5. What this does and does not show
- **One model, one export.** The integer codec is a post-training quantisation of one
model family with one recipe: per-channel 12-bit weights, activations at 2¹², no
retraining. Another model, a wider export or quantisation-aware training costs
something else, and this record does not say what.
- **One set of pictures.** 24 pictures of one source set at 768×512, whole. Rate and
quality are picture-dependent, so the record keeps every picture's figure.
- **What the BD-rate includes.** The integer codec's rate is its own: its hyper-decoder
decides the tables in integers, so its streams differ from the float codec's even before
its synthesis runs. The BD-rate is the cost of the whole integer codec at equal quality,
rate and distortion together.
- **Reproducibility.** An integer decode that gave the same bytes on every platform
reached is evidence of the construction on those platforms. It is not the ground of the
tier's claim (determinism-tiers §7). A float decode that reproduced on a platform here
says nothing of another platform, another build of the library or another device.
- **Time and energy.** Both hosts are shared, and the build host was under heavy load
from other work throughout; the record keeps the load average of every round. The
per-task count is the decoder's own CPU energy and nothing else; the GPU rail and the
package counter cover their whole device, and a figure from them is the round's marginal
over its idle brackets. The record's integer decoder is CPU code with the wide kernels of
`int_kernels` (NEON on arm64, portable Rust elsewhere), §4.6's with the narrow kernel sets
(NEON on arm64, AVX2 and AVX-512 on x86_64), and its GPU decode runs the graphs the
device takes through `wai-ops-gpu`; the float decode runs the library's own kernels. The
figures compare those implementations on those hosts, not integer and float arithmetic in
general.
- **What the per-task count covers on the build host.** It is the kernel's account of the
process's CPU energy. The float library's CPU kernels on that host may hand matrix work to
a matrix unit the CPU clusters share, and this record does not establish whether the
per-task count includes that unit's energy; so on the build host, the float codec's CPU
figure may be lower than the energy its decode caused. Host A's package counter has no
such gap for the CPU: it covers the whole package, the decode's share of it being the
marginal over the idle brackets. Whether it also covers the package's integrated GPU, the
interface does not state, so host A's figure for the integer decode with its graphs on that
GPU is the package's marginal and nothing more.
- **The encoder** is float in both codecs and is not measured.
## 6. Reproduce
```sh
W=/some/work/dir; T=wai/tools
python3 $T/wai_determinism_cost.py select $W <reference-root> # 24 pictures, checked
python3 $T/wai_determinism_cost.py export $W # 8 pinned checkpoints -> integer sets
python3 $T/wai_determinism_cost.py encode $W # both codecs; float decode in-process
python3 $T/wai_determinism_cost.py jobs $W native > jobs.tsv
wai_det_cost decode jobs.tsv > $W/int.native.tsv # the integer decodes (wai-rs bin)
python3 $T/wai_determinism_cost.py metrics $W
# per platform: wai_det_cost [--gpu] decode <jobs> > $W/xplat/<tag>.tsv (+ <tag>.json, the platform)
# wai_determinism_cost.py fdecode $W <tag> --device cpu|mps [--threads 1]
# per run: wai_det_energy.py --label L --counter task|ioreport-gpu|rapl -- <child> > $W/energy/L.json
python3 $T/wai_determinism_cost.py record $W wai/research/determinism-cost/record.json
python3 -I $T/wai_determinism_cost_verify.py wai/research/determinism-cost/record.json \
wai/research/determinism-cost.md wai/extensions/determinism-tiers.md
```
The scripts that ran each step on each host are in [`determinism-cost/runs/`](determinism-cost/runs/README.md).