diff options
| author | bitflash-maintainer <noreply@bitflash.invalid> | 2026-08-13 17:29:10 +0000 |
|---|---|---|
| committer | bitflash-maintainer <noreply@bitflash.invalid> | 2026-08-23 04:37:36 +0000 |
| commit | ee7613be2f1d679c7ea6e3948c44110313d230b1 (patch) | |
| tree | 1258dce7eba2e779d3ef1ff432d366e68d83a207 /src/main.cpp | |
| parent | 0620e69d8cee549ce64d323682a39129900a4f1c (diff) | |
size thread pools by the cores we are allowed, not the ones the host has
std::thread::hardware_concurrency() reports the MACHINE's core count. Inside a
container that is the wrong number: with --cpuset-cpus 0-5 on a 12-core host it
still answers 12, and every caller that sized a pool from it oversubscribed 2x.
Measured on the pool box:
- the pool node logged "Mining with 11 thread(s) of 12 core(s)" while
confined to 6 CPUs
- a burst miner launched with /hashthreads=2 filled the ~2 GB RandomX
dataset with 12 threads, alongside the pool node in the same 8 GB container
AvailableCoreCount() asks sched_getaffinity what the cpuset actually permits,
which is the number all of these meant. It cannot make the dataset build slower:
the CPU budget is identical either way, so fewer threads on the same cores is
the same work without the thrash. Falls back to hardware_concurrency where the
call is unavailable, and never returns 0 because callers subtract from it.
Not the cause of the burst miner dying -- that was a corrupt Berkeley DB
environment in the worker datadir -- but it is why the failure landed on the
dataset build, and it is wrong on its own terms.
(cherry picked from commit b3bee16f3eef8982bff1174bd9d0a9c21473732c)
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/main.cpp b/src/main.cpp index 11eb11d..62068d2 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -164,7 +164,7 @@ int MinerThreadCount() | |||
| 164 | { | 164 | { |
| 165 | if (nMinerThreads > 0) | 165 | if (nMinerThreads > 0) |
| 166 | return nMinerThreads; | 166 | return nMinerThreads; |
| 167 | unsigned int nCores = std::thread::hardware_concurrency(); | 167 | unsigned int nCores = AvailableCoreCount(); |
| 168 | if (nCores <= 1) | 168 | if (nCores <= 1) |
| 169 | return 1; | 169 | return 1; |
| 170 | return (int)(nCores - 1); | 170 | return (int)(nCores - 1); |
| @@ -3827,7 +3827,11 @@ connected: | |||
| 3827 | // ------------------------------------------------------------------ | 3827 | // ------------------------------------------------------------------ |
| 3828 | if (!RandomXFastReady()) { | 3828 | if (!RandomXFastReady()) { |
| 3829 | SetParticipantMiningStatus("building RandomX dataset (~2GB, one-time)"); | 3829 | SetParticipantMiningStatus("building RandomX dataset (~2GB, one-time)"); |
| 3830 | unsigned int nThreads = std::thread::hardware_concurrency(); | 3830 | // Fill with the cores we are permitted to use, not the ones the host |
| 3831 | // happens to have. More threads than the cpuset allows does not build | ||
| 3832 | // the dataset any faster -- the CPU budget is the same either way -- | ||
| 3833 | // it just oversubscribes, and this runs alongside the pool node. | ||
| 3834 | unsigned int nThreads = AvailableCoreCount(); | ||
| 3831 | RandomXInitDataset(nThreads > 0 ? (int)nThreads : 1); | 3835 | RandomXInitDataset(nThreads > 0 ? (int)nThreads : 1); |
| 3832 | } | 3836 | } |
| 3833 | LogPrint("worker", "[worker] RandomX dataset ready (%s)\n", | 3837 | LogPrint("worker", "[worker] RandomX dataset ready (%s)\n", |
| @@ -3866,7 +3870,7 @@ connected: | |||
| 3866 | // publish jobs to the threads, submit the shares they find. | 3870 | // publish jobs to the threads, submit the shares they find. |
| 3867 | // ------------------------------------------------------------------ | 3871 | // ------------------------------------------------------------------ |
| 3868 | int nWorkers = nHashThreads > 0 ? nHashThreads | 3872 | int nWorkers = nHashThreads > 0 ? nHashThreads |
| 3869 | : (int)std::thread::hardware_concurrency(); | 3873 | : (int)AvailableCoreCount(); |
| 3870 | if (nHashThreads <= 0) { | 3874 | if (nHashThreads <= 0) { |
| 3871 | if (nWorkers < 2) nWorkers = 2; | 3875 | if (nWorkers < 2) nWorkers = 2; |
| 3872 | nWorkers -= 1; // leave one core for node + I/O threads | 3876 | nWorkers -= 1; // leave one core for node + I/O threads |
| @@ -4177,7 +4181,7 @@ bool BitcoinMiner(int nThreadId) | |||
| 4177 | // Build the fast (~2 GB dataset) RandomX mode once, up front, so we're | 4181 | // Build the fast (~2 GB dataset) RandomX mode once, up front, so we're |
| 4178 | // not stuck mining in the much slower light/cache-only mode forever. | 4182 | // not stuck mining in the much slower light/cache-only mode forever. |
| 4179 | if (!RandomXFastReady()) { | 4183 | if (!RandomXFastReady()) { |
| 4180 | unsigned int nThreads = std::thread::hardware_concurrency(); | 4184 | unsigned int nThreads = AvailableCoreCount(); |
| 4181 | RandomXInitDataset(nThreads > 0 ? (int)nThreads : 1); | 4185 | RandomXInitDataset(nThreads > 0 ? (int)nThreads : 1); |
| 4182 | } | 4186 | } |
| 4183 | 4187 | ||