Ottimizza il kernel GPU: ~2x throughput sulla Quadro P4000
Tre modifiche, tutte a parità di risultato (verificate end-to-end): - Ammortamento della moltiplicazione scalare: prima scalar_mult_basic (l'operazione di gran lunga più costosa) veniva rieseguita a ogni batch, cioè 40 volte per kernel launch. Ora viene eseguita UNA sola volta per launch; il punto base P0 viene poi fatto avanzare di GPU_EC_BATCH_SIZE*G a ogni round con una semplice addizione EC affine, ripiegata nella batch inversion già presente (nuovo slot NEXT negli array Zj/prefix). La scalar mult è così ammortizzata su ~5120 chiavi invece di 128. - Una sola inversione di campo per round invece di due: la normalizzazione del nuovo P0 condivide l'inversione di Montgomery del batch. - Inversione modulare tramite la catena di addizione di libsecp256k1 (255 quadrati + 15 moltiplicazioni) al posto del quadrato-e-moltiplica ingenuo (~256 + ~128). Rimosso il vecchio modinv_fermat e la costante FIELD_P_MINUS_2 non più usata. - Rimosso l'array locale invZ[] (passaggio all'indietro fuso con la conversione affine + match), riducendo la memoria locale per-thread e migliorando l'occupancy. Misurato nello stesso ambiente/scheda: 15.0M -> ~30M keys/sec. Correttezza verificata end-to-end con privkey nota a offset 0, 50, 127, 128 (avanzamento del punto base), 200 e 5119 (40 avanzamenti consecutivi): tutte trovate con la chiave privata corretta. Nessun falso positivo su chiave pubblica valida casuale.
This commit is contained in:
@@ -63,7 +63,8 @@ There is no test suite in this repo.
|
||||
### `bruteforce/p2pk_bruteforce_gpu.cu` (GPU, CUDA, single file)
|
||||
- Same algorithmic strategy as the CPU version (Jacobian batch add + Montgomery batch inversion), but GMP doesn't run on-device, so 256-bit field arithmetic mod the secp256k1 prime is hand-written (`u256` = 4×uint64 limbs, schoolbook multiply via `unsigned __int128`, fast reduction using `2^256 ≡ 2^32+977 (mod p)`). Verified bit-for-bit against `secp256k1_ec_pubkey_create` before trusting it (see conversation/test methodology — no separate test file is checked in).
|
||||
- Each CUDA thread is an independent search lane (own random starting privkey, own local batch state), same as a CPU thread — just thousands of them instead of ~11. Per-thread batch size is `GPU_EC_BATCH_SIZE` (128), smaller than the CPU's 256, to keep per-thread local-memory footprint (Jacobian batch arrays) bounded across tens of thousands of concurrent threads.
|
||||
- Scalar multiplication on-device is plain double-and-add (no wNAF/windowing/precomputed tables like libsecp256k1 has on CPU) — the main further-optimization opportunity if more speed is needed.
|
||||
- Scalar multiplication (`scalar_mult_basic`, plain double-and-add) runs **once per kernel launch**, not once per batch: the base point P0 is then advanced by `GPU_EC_BATCH_SIZE·G` each round via a cheap affine EC add folded into the batch inversion (the `NEXT` slot in the Zj/prefix arrays), so the expensive scalar mult is amortized over all `GPU_OUTER_ITERS_PER_LAUNCH × GPU_EC_BATCH_SIZE` keys. There is exactly one field inversion per round (Montgomery batch trick), done with the libsecp256k1 addition-chain `modinv` (255 sqr + 15 mul), not naive square-and-multiply.
|
||||
- Remaining optimization headroom: double-and-add scalar mult (no wNAF/windowing), schoolbook `mulmod`, and occupancy tuning (grid size / batch size vs per-thread local memory).
|
||||
- Host side still uses libsecp256k1 (CPU) only for one-time setup: precomputing G-multiples and validating/loading target keys into a host-sorted array + Bloom filter, both uploaded once to device memory. Device-side matching = Bloom filter check + binary search over the sorted target array.
|
||||
- `NVCC_ARCH` in the Makefile defaults to `sm_61` (Pascal) — must match the actual GPU (`make gpu-info` shows compute capability via `nvidia-smi`, then pick the matching `sm_XX`).
|
||||
- On WSL2, the NVIDIA driver comes from the Windows host (visible as `nvidia-smi` working out of the box) — only the CUDA Toolkit needs installing inside WSL, never a driver.
|
||||
|
||||
Reference in New Issue
Block a user