Three scheduling changes measured against the #23 kernel, three interleaved
rounds each, parity clean on every host:
- Batches are rounded up to whole grids, two per batch by default
(MINER_CUDA_BATCH_ALIGN, MINER_CUDA_BATCH_WAVES). The CLI's 1M-nonce
batch left a half-empty tail wave and paid the launch gap every 1M
hashes. beast +1.6% for one grid, +0.4% more for two; benjy +0.5% for
the second grid; quadbrat neutral.
- LAIR_EARLY_REJECT: the second permutation stops before its last linear
layer, computes output 0 alone (the hash's top 64 bits) and rejects on
it; only the rare survivors pay for the other eleven outputs. +0.6%.
- LAIR_NONCE_DIR: the host precomputes the state after the first linear
layer for the batch's first nonce (first_layer_after_absorb, unit test
against the matrix column), and the kernel derives each nonce's state
as that plus a scalar times column 7 of the external matrix; nonces
past a carry out of the low limb take the old path. +0.25% on beast,
+0.6% on the 4090 and 3060.
Also tried and rejected: 512-thread blocks (-0.4%), a smaller grid via
MINER_CUDA_THREADS_PER_SM=16384 (-0.6%), a larger one (65536, within
noise of two waves), and the whole S-box as one PTX block, which
compiles to byte-identical SASS. The threads-per-block knob
(MINER_CUDA_THREADS_PER_BLOCK with LAIR_TPB) stays for experiments.
beast 2x5090: 2146 -> ~2206 MH/s (+2.8%); benjy 4090: 711 -> ~718;
quadbrat 3060: 140.2 -> 141.2.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ue5ZZm1Hiv5zPnucykKKuF