engine-cuda: deferred carries, carry-flag arithmetic, one nonce per thread #17

Merged
grenade merged 2 commits from cuda/tuning into main 2026-09-03 13:01:47 +00:00
Owner

#3 step 5. Kernel tuning measured on benjy (RTX 4090 at 250 W, miner paused, interleaved rounds); every variant passed parity against pow_core before it was timed.

variant MH/s
straight port (#16) 297 to 305
grid cap 32768 threads/SM (one nonce per thread up to 4M) 304
deferred-carry linear layers 344
carry-flag gf_add / gf_reduce via inline PTX 385
carry-flag accumulators 414

2.86x origin's wgpu build on the same card and limit. Part of the gain is indirect: fewer instructions per hash let the power-capped card boost from 1920 to 1995 MHz.

Rejected by measurement: __noinline__ permute (13 percent slower, so code size was not the limit), -maxrregcount 80 and 64 (flat), internal-round unroll 1 or 22 (flat).

Batch size (#6 for the CUDA engine): with the old grid cap of 1M threads, batches above 1M looped nonces per thread and lost up to 4 percent; with the cap at 4M threads every batch size from 1M to 16M lands at 304 to 306. So batch size is irrelevant to throughput here and stays at 1M, which keeps stale work per job switch smallest.

Every knob remains a -D macro reachable through MINER_NVCC_FLAGS, so the harness can keep testing variants without code changes. The bench run on this PR is the full-protocol confirmation (5 x 30 s, parity 25).

Not measured: sm_120. Its compile used 255 registers with 100 bytes of spill on the earlier kernel, against 128 and 16 on Ada, which is a different codegen outcome and needs beast to evaluate.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CBgs2nSi4H2mdh8kD8vMX5

#3 step 5. Kernel tuning measured on benjy (RTX 4090 at 250 W, miner paused, interleaved rounds); every variant passed parity against `pow_core` before it was timed. | variant | MH/s | | --- | --- | | straight port (#16) | 297 to 305 | | grid cap 32768 threads/SM (one nonce per thread up to 4M) | 304 | | deferred-carry linear layers | 344 | | carry-flag `gf_add` / `gf_reduce` via inline PTX | 385 | | carry-flag accumulators | **414** | **2.86x** origin's wgpu build on the same card and limit. Part of the gain is indirect: fewer instructions per hash let the power-capped card boost from 1920 to 1995 MHz. Rejected by measurement: `__noinline__` permute (13 percent slower, so code size was not the limit), `-maxrregcount` 80 and 64 (flat), internal-round unroll 1 or 22 (flat). **Batch size** (#6 for the CUDA engine): with the old grid cap of 1M threads, batches above 1M looped nonces per thread and lost up to 4 percent; with the cap at 4M threads every batch size from 1M to 16M lands at 304 to 306. So batch size is irrelevant to throughput here and stays at 1M, which keeps stale work per job switch smallest. Every knob remains a `-D` macro reachable through `MINER_NVCC_FLAGS`, so the harness can keep testing variants without code changes. The `bench` run on this PR is the full-protocol confirmation (5 x 30 s, parity 25). Not measured: `sm_120`. Its compile used 255 registers with 100 bytes of spill on the earlier kernel, against 128 and 16 on Ada, which is a different codegen outcome and needs beast to evaluate. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01CBgs2nSi4H2mdh8kD8vMX5
grenade added 1 commit 2026-09-03 12:51:33 +00:00
engine-cuda: deferred carries, carry-flag arithmetic, one nonce per thread
All checks were successful
ci / fmt (pull_request) Successful in 21s
ci / clippy (pull_request) Successful in 1m43s
ci / doc (pull_request) Successful in 1m41s
ci / test (pull_request) Successful in 6m52s
2bf3246634
quantus/miner#3 step 5, measured on benjy (RTX 4090, 250 W, miner paused,
interleaved rounds, parity verified on every variant):

  variant                                  MH/s
  straight port (PR #16)                   297-305
  + grid cap 32768 threads/SM              304   (1 nonce per thread up to 4M)
  + deferred-carry linear layers           344   (+13%)
  + carry-flag gf_add / gf_reduce (PTX)    385   (+12%)
  + carry-flag accumulators                414   (+7%)

414 MH/s is 2.86x origin's wgpu build (144.4) on the same card and limit.
Fewer instructions per hash also let the power-capped card clock higher
(1920 -> 1995 MHz), which is part of the gain.

Rejected by measurement: __noinline__ permute (-13%: code size was not the
limit, the call convention was), -maxrregcount 80/64 (flat), internal-round
unroll 1 or 22 (flat, within noise of 2).

The batch sweep found batch size irrelevant once the grid keeps one nonce
per thread (304-306 MH/s from 1M to 16M); batch stays at 1M for the
smallest stale cost. All knobs remain as -D macros and MINER_NVCC_FLAGS
so the harness can keep testing variants.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CBgs2nSi4H2mdh8kD8vMX5
grenade added 1 commit 2026-09-03 12:56:28 +00:00
engine-cuda: fold round constants into the preceding linear layer; bench on cuda paths
All checks were successful
ci / fmt (pull_request) Successful in 23s
bench / build (pull_request) Successful in 1m0s
ci / clippy (pull_request) Successful in 1m57s
bench / measure (pull_request) Successful in 2m51s
ci / doc (pull_request) Successful in 1m52s
ci / test (pull_request) Successful in 7m25s
b640d3a711
Each linear layer now folds the constant of the round that follows it into
its final deferred-carry reduction (or, for the internal rounds, into the
element-0 multiply-add), removing the per-element gf_add before every S-box.
Parity verified. On benjy the effect is within run-to-run noise: three
interleaved rounds gave medians of 418.5 vs 409.7 MH/s against the previous
default, with SM clock swinging 1935-2025 MHz across rounds. Kept on as
LAIR_FOLD_RC=1 for the instruction count; not claimed as a measured gain.

bench.yaml: crates/engine-cuda/** now triggers the harness on PRs. The
previous PR's kernel changes did not run it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CBgs2nSi4H2mdh8kD8vMX5

quantus-bench b640d3a711 on benjy.hanzalova.internal

worker median MH/s spread windows
0 408.27 0.2% 407.8, 408.4, 407.7, 408.3, 408.5

total median: 408.27 MH/s (batch 1000000, 5 x 30s, engine gpu-cuda)

  • gpu 0 NVIDIA GeForce RTX 4090: driver 580.173.02, limit 250 W, draw 251 W, sm 1950 MHz, 58 C
  • parity: OK (25/25 jobs found solutions, all verified against CPU)
    --- resume miner ---
    active
## quantus-bench b640d3a711070c75850ab17afb15b5d37039e411 on benjy.hanzalova.internal | worker | median MH/s | spread | windows | | --- | --- | --- | --- | | 0 | 408.27 | 0.2% | 407.8, 408.4, 407.7, 408.3, 408.5 | total median: **408.27 MH/s** (batch 1000000, 5 x 30s, engine gpu-cuda) - gpu 0 NVIDIA GeForce RTX 4090: driver 580.173.02, limit 250 W, draw 251 W, sm 1950 MHz, 58 C - parity: OK (25/25 jobs found solutions, all verified against CPU) --- resume miner --- active
grenade merged commit ad66f1334f into main 2026-09-03 13:01:47 +00:00
grenade deleted branch cuda/tuning 2026-09-03 13:01:47 +00:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: blackbeard/miner#17