Dependent integer multiplication and wider-state experiments
Measured 2026-09-10 UTC on the existing M4 laptop, Graviton5 parent, and Hetzner EPYC Genoa guest. Graviton5 has a reproducible advantage for the tested nonlinear low-half multiply-add chains, including wider mixed states. It does not win every multiplication workload: the M4 wins multiply-high, and this Hetzner machine wins the explicitly SIMD 32-bit implementation.
These are instruction-mix experiments, not cryptographic constructions or time-lock security bounds. Small state, chosen constants, and lack of cryptanalysis make these unsuitable as a replacement for RandomX. Nonlinear mixing prevents the most obvious affine recurrence simplification; it does not prove the absence of shortcuts, ASIC advantages, cycles, or attacks.
Final measurements
Nanoseconds per whole dependent round, median of three runs of one billion rounds each; smaller is faster. One software thread throughout. A four-lane round updates all four lanes and mixes neighboring results; its displayed rate is not the sum of four independent chains.
| Same workload, best tested implementation | Graviton5 | M4 | Hetzner Genoa | Graviton speedup over M4 / Hetzner |
|---|---|---|---|---|
| 64-bit low multiply-add, rotate, XOR | 0.911 | 1.388 | 1.656 | 1.52x / 1.82x |
| 64-bit multiply-high, rotate, add, XOR | 1.552 | 1.151 | 1.655 | 0.74x / 1.07x |
| Four 64-bit multiply-add lanes, then mix | 1.217 | 1.677 | 1.940 | 1.38x / 1.59x |
| Four 32-bit multiply-add lanes, then mix | 1.217 | 1.638 | 1.928 | 1.35x / 1.58x |
For the last row, scalar code wins on both ARM machines; explicit SIMD wins on Hetzner. The explicitly SIMD-only results are 3.416 / 2.407 / 1.928 ns for Graviton / M4 / Hetzner. Merely widening to SIMD made this serial ARM workload slower. Four 64-bit lanes use scalar integer multiplication, not four SIMD 64-bit multiplies: ordinary NEON has no direct 64-bit lane multiplication.
The low-half Graviton result is about 1.10 billion rounds/second on one core, versus 720 million on M4 and 604 million on Hetzner. These very small rounds must not be compared numerically with RandomX hashes, SHA digests, or delay security. They contain radically different amounts and kinds of work.
summary.json retains medians, ranges, exact output checksums, and winning
binary names for every variant, including alternatives omitted from this table.
M4 timing varies more than the servers: its ordinary low-chain final samples
span 1.407โ1.575 ns. The table uses the optimized equivalent variant, whose
samples span 1.375โ1.466 ns. These differences are short-run estimates rather
than guaranteed sustained device limits.
Semantics and optimization
Arithmetic is unsigned modulo the word size. Constants are
C = 0xd1342543de82ef95, D = 0x9e3779b97f4a7c15; 32-bit code truncates them.
All single-state chains start at 1; all four-lane states start [1,2,3,4].
low:x = rotl64(x*C+D,17) XOR (old_x >> 23).high:x = high64(x*(x XOR C)) XOR (rotl64(x,27)+D).wide64: computey[i]=x[i]*C+Dfor four lanes, then simultaneouslyx[i]=rotl64(y[i],17) XOR y[(i+1)%4].wide32andwide32s: the same four-lane rule with 32-bit words and rotate by 11. They are exact semantic equivalents with vector and scalar source formulations respectively.
Each new round consumes the preceding round's state. Adjacent-lane mixing propagates influence through the full state over several rounds; this is not claimed to be full cryptographic diffusion in a single round.
For each host we tested loop unroll factors 1, 4, and 16, both normal compiler optimization and auto-vectorization disabled. Each configuration ran twice at 100 million rounds in the final sweep. The fastest mean configuration for each source variant was then measured independently three times at one billion rounds. The table selects the faster median when source variants have identical semantics. This is a finite optimization search, not a proof of optimal machine code. The chosen binaries and generated assembly are retained.
Native ARM assembly uses MADD and UMULH. The x86 code uses IMUL/MUL,
and the 32-bit vector implementation uses VPMULLD, VPADDD, VPSHUFD,
VPROLD, and VPXOR (the exposed AVX-512 support is used). Disabling automatic
vectorization helps avoid unfavorable SIMD choices for some scalar formulations.
The explicit vector type remains vectorized in these control builds.
Apple Clang originally emits MADD, then a standalone rotate, then XOR with
the shifted previous state. GCC on Graviton shifts the old state alongside
MADD and folds the rotate into EOR. The lowopt ARM inline-assembly variant
explicitly implements the latter schedule on both ARM machines. It gives no
large M4 improvement and preserves Graviton's advantage. On x86 lowopt calls
the same low-chain function; small differences are code placement or run noise.
The low-chain data dependency in the inspected Graviton assembly is
MADD -> EOR-with-rotate; the old state's LSR can execute alongside MADD.
The analogous x86 path is IMUL -> ADD -> RORX -> XOR, with the old-state
shift independent of the multiply path. This difference provides a concrete
explanation for the measured advantage. These are assembly dependency paths,
not a separate measurement of individual instruction latency. The explicit
ARM schedule is:
madd t, x, C, D
lsr old, x, #23
eor x, old, t, ror #47
Accumulator dependency control
A deliberately affine diagnostic repeats x = a*b+x for constant operands.
It is trivially shortcuttable and excluded from nonlinear results above.
The first acc version obscures the multiplier operands from the optimizer,
but unrolling can still reassociate additions. This produced misleadingly low
Graviton times (~0.168 ns), so it is not evidence of that fast a dependent
accumulator instruction.
accforced.c additionally makes the accumulator opaque at each iteration,
preventing compiler reassociation while retaining the actual hardware
dependency. Unroll-16, three one-billion-step runs give:
| Forced accumulator dependency | Graviton5 | M4 | Hetzner |
|---|---|---|---|
| ns/update | 0.304 | 0.235 | 0.277 |
This is a roughly one-cycle accumulator path on Graviton at 3.3 GHz. An x86 core can overlap the independent multiplies and serialize only the adds, so fused MADD does not by itself create an advantage in this specific recurrence. These control results match the exact final checksum of the original diagnostic.
Correctness, environment, and reproduction
run.py independently computes every workload in Python for 1,024 rounds and
checks each binary before timing it. It also checks equal final checksums for
all implementations of the same workload. summarize.py verifies that all
one-billion-round final checksums agree across all three platforms, including
the scalar/SIMD and low/lowopt equivalents and accumulator controls. Source
files transferred to the servers match the saved local files byte for byte.
The four-lane return value is a folded checksum of the final state.
- M4: Apple Clang 17.0.0, native arm64,
-O3 -mcpu=native -std=c11, with-DUNROLL=1,4, or16. No-vector controls add-fno-vectorize -fno-slp-vectorize. macOS chooses the physical core; no hard pin, P-core residency assertion, or clock adjustment. Existing applications remain. - Hetzner: GCC 13.3.0,
-O3 -march=native -std=c11, same unroll factors; no-vector controls add-fno-tree-vectorize. One thread pinned to guest CPU 2. This is not proof of a physically exclusive host core or disabled host SMT. Existing production services remain active. - Graviton5: GCC 12.2.0 from the existing
attested-relay-arm-toolchain:20260909Docker image,-O3 -mcpu=native -std=c11, same unroll factors and GCC no-vector flag. Builds used no network. Executables ran natively on the parent pinned to CPU 14. The production enclave, its CPUs 1โ12, and its warm-up were preserved. Build containers remain stopped. No global CPU/page/cache settings changed.
Other agents' benchmark and build workloads were paused for the final sweeps and confirmation runs. This does not eliminate preexisting production load, Mac applications, hypervisor effects, or unknown physical co-tenants. Different compilers mean these compare the optimized available implementations, not compiler-controlled isolated microarchitecture performance.
Compile bench.c with the flags above to bench-u1, bench-u4, bench-u16,
and bench-novec-u1, bench-novec-u4, bench-novec-u16. Then run, using the
appropriate host name and CPU (empty string on macOS):
python3 run.py local-sweep '' 100000000
python3 final.py local
For Linux, substitute hetz-sweep 2 / hetz 2 or graviton-sweep 14 /
graviton 14. Compile accforced.c with the corresponding native flags and
-DUNROLL=16, then run accforced acc 1000000000 three times with the same pin.
summarize.py regenerates the combined summary from the archived host layouts.
Raw stdout, parsed results, environment metadata, assembly, source, and
executables are retained under this directory. SHA256SUMS covers the files.
The practical lead is low-half integer multiplication with fused addition and dependent bit mixing, not multiplication generally or SIMD generally. Whether incorporating this mix into RandomX changes its platform balance or security requires a separate design and implementation study.