HostWorkerPool: half the budget, MR placements reserve 16 B per grid point, output unchanged

Without a GPU (macOS), rc176's worker pool - 1/3 of the 12.9 GB budget on a 16 GB Mac - let only two
molecular-replacement placements run at once, as each reserved 32 B per grid point (2.1 GB on 4nwv)
against a measured ~0.95 GB. MR rescoring went from 38.6 s to 69 s and 4nwv's wall time from 402 s
(budget off) to 444 s.

On the M6 Mac mini (16 GB), 4nwv, two runs each in alternating order on a quiet machine:
- old build 234774ff0: 418.4 s, 20.0-21.3 GiB peak footprint, 576-682k swapouts
- rc176 as shipped: 444.2 s, 14.5-15.2 GiB, 39-66k swapouts
- this change: 402.4 s, 15.5-15.8 GiB, 66-93k swapouts
- budget switched off: 401.7 s, 21.8-23.3 GiB, 268-433k swapouts
9zlo/9s02/9gjx: 71.9/79.0/82.8 s (old build 73.6/82.2/83.6), no swap. p.hkl byte-identical in every
run: the pool decides only what runs at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018My7tqt8a4LyKKjP3FhScT
This commit is contained in:
leonarski_fandClaude Opus 5.5 committed 2026-10-18 08:42:02 +02:00
1 parent 366079ca62
commit 6f361ccde5
3 files changed
+5 -2

No files matched your search

+1 -1
View File
@@ -22,7 +22,7 @@ size_t DefaultHostMemoryBudget();
// The share of the budget that the large per-worker buffers of parallel steps - a translation function's
// grids, a null replicate's model maps - may hold at once. The rest is what the run holds beside them:
// its reflections, its merge, the detector-sized arrays.
constexpr double HOST_WORKER_POOL_FRACTION = 1.0 / 3.0;
constexpr double HOST_WORKER_POOL_FRACTION = 0.5;
// One pool for those buffers, process-wide. A worker reserves its bytes before it makes them and hands
// them back when it is done; one that would take the pool past its size waits until others have handed
@@ -36,3 +36,6 @@ size_t ModelGridPoints(const gemmi::UnitCell &cell, const gemmi::SpaceGroup *sg,
// and the bulk-solvent mask grids, and for each of them its transform's input copy, spectrum and coefficients,
// with the two made at once (ModelValidation's compute_model_factors).
constexpr size_t MODEL_FACTORS_BYTES_PER_GRID_POINT = 32;
// What a molecular-replacement placement's structure factors and rigid body hold on the CPU at their peak, per
// point of that grid: measured at under half of the above.
constexpr size_t MODEL_PLACEMENT_BYTES_PER_GRID_POINT = 16;
@@ -2777,7 +2777,7 @@ MolecularReplacementResult search_model(const SearchModel &model, const std::vec
// gigabyte or more of grids on a large cell, so each reserves them against the host's worker
// pool first (HostWorkerPool), as a null replicate does.
const size_t placement_bytes = get_gpu_count() == 0
? MODEL_FACTORS_BYTES_PER_GRID_POINT * ModelGridPoints(cell, &sg, d_min)
? MODEL_PLACEMENT_BYTES_PER_GRID_POINT * ModelGridPoints(cell, &sg, d_min)
: 0;
for (First *f : to_refine)
running.push_back(std::async(std::launch::async, [&, f] {