RotationScaleMerge::RunArm: free the fulls before growing them
When a chain needs more fulls than the arrays hold, fulls and fulls_staging are released before the resize. The gather overwrites every field, so growing in place only copied the previous chain's records into the new allocation to be overwritten. The expected saving (a few tenths of a second on 8tyy) is below the run-to-run noise of the wall clock: 8tyy median of 3, 127.0 s without vs 129.6 s with, under different machine load. 8qaw max RSS 21.9 -> 21.7 GB. p.mtz md5-identical to rc175 on myoglobin, cytochrome C (also at -N 4 and -N 8), thaumatin, 8a1a, 8tyy, 9gdj and 8qaw. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SVmAWnzCmRKAXVUCdc4iNi
This commit is contained in:
@@ -6476,7 +6476,13 @@ RotationScaleMerge::Result RotationScaleMerge::RunArm(bool scale_partials, bool
|
||||
|
||||
// resize, not assign: the gather below writes every field of every full, so zeroing 80 bytes
|
||||
// each first is a few hundred megabytes of pure write traffic per chain. The staging arrays are
|
||||
// members for the same reason.
|
||||
// members for the same reason. Nothing in them survives the gather either, so when they have
|
||||
// to grow they are freed first: growing in place would copy the previous chain's records into
|
||||
// the new allocation only for the gather to overwrite them.
|
||||
if (static_cast<size_t>(nf) > fulls.capacity()) {
|
||||
fulls = {};
|
||||
fulls_staging = {};
|
||||
}
|
||||
fulls.resize(nf);
|
||||
FullsStaging &st = fulls_staging;
|
||||
st.Resize(nf);
|
||||
|
||||
Reference in New Issue
Block a user