From 65eb86ab66d3c58183990c1900f39fe7d234e697 Mon Sep 17 00:00:00 2001 From: jungfrau Date: Mon, 17 Aug 2026 18:05:19 -0400 Subject: [PATCH] Size the post-refine gather by its reflections, not by its frames Both passes of the gather are chunked over OUTCOMES, one per frame, but their cost is the tens of thousands of reflections inside each. ThreadsForWork was being asked about the frames: a rotation dataset has on the order of a thousand of them against a floor of 32768 items per thread, so it answered 1, and the pass that walks every reflection in the run ran on a single thread on every dataset in the test set. RotationScaleMerge::Ingest does the identical thing and asks with the observation count, which is what makes this an inconsistency rather than a tuning choice. The reflection total is already to hand a few lines up. The split is unchanged - only the worker count moves - so the output is identical. Measured on the heaviest crystal: the phase drops 33 %, from 8.6 s to 5.5 s, and its mean occupancy goes from 4.1 threads to 12.3. Co-Authored-By: Claude Opus 5 --- image_analysis/geom_refinement/PostRefine.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/image_analysis/geom_refinement/PostRefine.cpp b/image_analysis/geom_refinement/PostRefine.cpp index 21948c46..25f23ef1 100644 --- a/image_analysis/geom_refinement/PostRefine.cpp +++ b/image_analysis/geom_refinement/PostRefine.cpp @@ -136,8 +136,14 @@ PostRefineResult PostRefineRotationGeometry(const std::vector pts_offset(n_out + 1, 0); - ParallelChunks(n_out, ThreadsForWork(static_cast(n_out), nthreads), [&](int lo, int hi) { + ParallelChunks(n_out, gather_threads, [&](int lo, int hi) { for (int o = lo; o < hi; o++) { size_t keep = 0; for (const auto &r : outcomes[o].reflections) @@ -151,7 +157,7 @@ PostRefineResult PostRefineRotationGeometry(const std::vector pts(pts_offset[n_out]); - ParallelChunks(n_out, ThreadsForWork(static_cast(n_out), nthreads), [&](int lo, int hi) { + ParallelChunks(n_out, gather_threads, [&](int lo, int hi) { for (int o = lo; o < hi; o++) { size_t at = pts_offset[o]; for (const auto &r : outcomes[o].reflections) {