tandem rng tandem-mlx GitHub

Performance

pixi run bench produces the figures, in its own environment with PyObjC for the MPS baseline.

GPU

Apple M4 Pro, MLX 0.32.3, one session. A run issues ten calls back to back and evaluates them together. The table gives the best of five runs after a warm-up, in GiB/s of output. mx.random uses its default threefry key. The baseline is MPSMatrixRandomPhilox, Philox4x32-10 from Metal Performance Shaders, timed the same way with ten fills in one command buffer. MPS has no bounded integers and no exponentials, so those rows compare with its uint32 words or float32 uniforms, marked *.

draw log2 n tandem_mlx MPS Philox mx.random
uniform float32 24 152 162 20
bits uint32 24 165 165 -
randint int32 in [0, 1000) 24 173 166* 12
normal float32 24 170 105 14
normal float32, odd start 24 152 105 -
exponential float32 24 174 163* -
uniform float32 26 173 145 20
bits uint32 26 164 146 -
randint int32 in [0, 1000) 26 145 145* 11
normal float32 26 159 108 15
normal float32, odd start 26 159 109 -
exponential float32 26 178 164* -

Tandem and MPS Philox both run near the GPU's integer throughput on the plain draws. The MPS normals run at two thirds of its uniform rate, while the Tandem Box-Muller pass adds little to the fill.