diff options
| author | Bitflash <btf01@proton.me> | 2026-07-31 11:27:50 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-07-31 11:27:50 -0300 |
| commit | f05274afd0becc7311fa69aa60b0215f300e5f28 (patch) | |
| tree | 85f5842158688f59bfe88e3349866687ce0e5551 /src/main.cpp | |
| parent | cca4e0c38595653846d9907650870df8c0768d77 (diff) | |
randomx: allocate the dataset once, not once per miner thread (#68)
Every miner thread calls RandomXInitDataset at startup. Its only guard is
g_fFast, which is set at the very end -- after the ~2 GB dataset has been
filled, which takes tens of seconds. So all of them sailed past the guard
together and each allocated its own dataset.
Measured in production on a 32-core machine running 31 miner threads: the
log says "initializing ~2 GB dataset" 34 times, and the process holds
65,127 MB of private pages while its own startup line promises 2142 MB
"(~2080 MB shared RandomX dataset + ~2 MB per thread)". The word shared
was not true. A 4-core machine showed the same thing at its own scale: 4
allocations for 3 threads.
The waste was the mild half. g_dataset is assigned the moment memory is
allocated, before it holds anything, so the last thread to allocate swung
the pointer out from under threads still filling their own. A miner could
then hash against a dataset another thread had not finished writing, and
proof of work computed that way is not reproducible by any other node --
the block would be found invalid by everyone, including this node's own
verifier, which uses the cache rather than the dataset.
This only became reachable with multi-threaded mining (#52); with one
thread there was nobody to race.
Holding the lock across the whole initialisation is deliberate: a thread
arriving mid-init has nothing useful to do until the dataset exists, and
blocking is how it waits for exactly that.
Verified with three mining threads: one "initializing ~2 GB dataset", one
"dataset ready", and 2362 MB of private memory against 2086 MB advertised
-- the difference being the 256 MB cache. Before, three threads meant three
datasets.
Diffstat (limited to 'src/main.cpp')
0 files changed, 0 insertions, 0 deletions