Problem 2527 - G4RegionStore::UpdateMaterialList() called even if geometry unchanged costing performance
Summary: G4RegionStore::UpdateMaterialList() called even if geometry unchanged costing...
Status: NEW
Alias: None
Product: Geant4
Classification: Unclassified
Component: run (show other problems)
Version: other
Hardware: All All
: P4 minor
Assignee: asai
URL:
Depends on:
Blocks:
 
Reported: 2023-01-26 13:48 CET by Stephan Lachnit
Modified: 2023-01-26 13:58 CET (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this problem.
Description Stephan Lachnit 2023-01-26 13:48:30 CET
We have found a possible performance improvement for sequential runs without changed geometry.

In our use case (https://allpix-squared.docs.cern.ch/) we create many runs with mostly one particle while not touching the geometry. We noticed that when adding many volumes (imagine e.g. five 800x800 pixel detectors) the RunInitialization() method in BeamOn() takes a significant amount of time. After profiling the culprit was pinned down to G4RegionStore::UpdateMaterialList().
The full call tree:

G4RunManager::BeamOn()
G4RunManager::RunInitialization()
G4RunManagerKernel::RunInitialization
G4RunManagerKernel::UpdateRegion()
G4RegionStore::UpdateMaterialList()

In Allpix Squared we worked around this using implementing a custom Run Manager based on the WorkerRunManager. A minimal working implementation of it can be found here: https://github.com/stephanlachnit/Geant4MWE/tree/runManagerTest

This works because G4RunManagerKernel::UpdateRegion() explicitly checks if runManagerKernelType is workerRMK and skips G4RegionStore::UpdateMaterialList() in that case. It is not clear to me why this is implemented in such a way.

With this setup, we can significantly improve performance:

# 1x BeamOn(100)
## customWorkerMTRunManager
Result Prep:  49600 ms
Result Bench: 0 ms
## G4MTRunManager
Result Prep:  49638 ms
Result Bench: 372 ms
## G4RunManager
Result Prep:  48381 ms
Result Bench: 350 ms
# 10x BeamOn(10)
## customWorkerMTRunManager
Result Prep:  47786 ms
Result Bench: 1 ms
## G4MTRunManager
Result Prep:  47768 ms
Result Bench: 2689 ms
## G4RunManager
Result Prep:  48917 ms
Result Bench: 2682 ms
# 100x BeamOn(1)
## customWorkerMTRunManager
Result Prep:  49147 ms
Result Bench: 12 ms
## G4MTRunManager
Result Prep:  50295 ms
Result Bench: 26965 ms
## G4RunManager
Result Prep:  50427 ms
Result Bench: 26690 ms


All benchmarks were run on one thread only. You can run these benchmarks yourself from the code in the repo.

It's clear that the actual benchmark ("Result Bench") scales linearly with the amount of calls to BeamOn() and not the actual number of simulation runs which is identical in all three cases.

From my limited understand I think there is a check to GeometryHasChanged() missing, and if this function is insufficient to test if G4RegionStore::UpdateMaterialList() needs to be called then another check should be implemented. I assume complex geometry does not only apply to Allpix Squared but ATLAS, CMS, etc simulations as well.