Skip to content

[hist] Pause filling during snapshot - #23093

Open
hahnjo wants to merge 1 commit into
root-project:masterfrom
hahnjo:hist-snapshot-pause
Open

[hist] Pause filling during snapshot#23093
hahnjo wants to merge 1 commit into
root-project:masterfrom
hahnjo:hist-snapshot-pause

Conversation

@hahnjo

@hahnjo hahnjo commented Aug 18, 2026

Copy link
Copy Markdown
Member

FillAtomic is much faster than SnapshotAtomic, so in case of heavy contention it would starve the snapshot. By adding a new atomic flag FillAtomic can pause while a Snapshot is running. The successful double collect is still needed if a thread is already in FillAtomic.

If SnapshotAtomic is not used, the performance impact of the added check is minimal / not measurable because fSnapshot is always false and already in the cache line of the RHistEngine.

@hahnjo
hahnjo requested review from hageboeck and jblomer August 18, 2026 11:48
@hahnjo hahnjo self-assigned this Aug 18, 2026
@hahnjo hahnjo added the in:Hist label Aug 18, 2026
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown

Test Results

    23 files      23 suites   3d 15h 3m 0s ⏱️
 3 862 tests  3 861 ✅ 0 💤 1 ❌
78 678 runs  78 677 ✅ 0 💤 1 ❌

For more details on these failures, see this check.

Results for commit 863501e.

♻️ This comment has been updated with latest results.

Comment thread hist/histv7/inc/ROOT/RHistEngine.hxx
Comment thread hist/histv7/test/hist_engine_atomic.cxx
@hahnjo
hahnjo force-pushed the hist-snapshot-pause branch from a14b914 to 313652f Compare August 19, 2026 12:01
Comment thread hist/histv7/test/hist_io.cxx Outdated

@pcanal pcanal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks.

Comment thread hist/histv7/inc/ROOT/RHistEngine.hxx Outdated
Comment on lines +152 to +153
std::swap(fAxes, rhs.fAxes);
std::swap(fBinContents, rhs.fBinContents);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can a snapshot be in progress while this is called? Maybe it's OK to assume that the answer is "no", because moving from something that's in use is likely a problem.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we can assume here that no snapshot is in progress, only few methods are allowed to be called concurrently (basically FillAtomic). Exact guarantees will need to be documented in a later PR.

Comment thread hist/histv7/test/hist_engine_atomic.cxx
Comment thread hist/histv7/inc/ROOT/RHistEngine.hxx Outdated
Comment on lines +873 to +877
do {
while (fSnapshot.load(std::memory_order_relaxed)) {
// Spin while another snapshot is running
}
} while (fSnapshot.exchange(true, std::memory_order_relaxed));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
do {
while (fSnapshot.load(std::memory_order_relaxed)) {
// Spin while another snapshot is running
}
} while (fSnapshot.exchange(true, std::memory_order_relaxed));
// Spin while another snapshot is running and reserve our turn
bool expected = false;
while (! fSnapshot.compare_exchange_strong(expected, true, std::memory_order_relaxed));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proposed code is worse because compare-exchange evicts the cache line (holding RHistEngine) on every iteration. See also the section on optimizations in https://en.wikipedia.org/wiki/Spinlock and test-and-test-and-set lock (TTAS).

FillAtomic is much faster than SnapshotAtomic, so in case of heavy
contention it would starve the snapshot. By adding a new atomic flag
FillAtomic can pause while a Snapshot is running. The successful
double collect is still needed if a thread is already in FillAtomic.

If SnapshotAtomic is not used, the performance impact of the added
check is minimal / not measurable because fSnapshotInProgress is
always false and already in the cache line of the RHistEngine.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants