TL;DR: 1) Can G4Cache
instances be used across multiple instances within a thread, or is it a thread-local singleton? 2) Can I initialize a data member reference using G4Cache::Get()
in the constructor?
I’m working on reducing the memory footprint for meshed electric field models in the G4CMP library. My goal is to have one mesh per type of detector, shared across all threads, and all instances (detector volumes) within each thread.
My meshing object (G4CMPVMeshInterpolator
base class) has huge arrays which are initialized during the construction and setup process (on the master thread), but during tracking there’s just a single G4int index for “last simplex used” that needs to be mutable.
To support sharing a single instance, I read the documentation for using G4Cache
, and modified my class thus:
// Per-instance storage to remember last tetrahedron used
mutable G4Cache<G4double> TetraIdxStore;
G4double& TetraIdx;
In the base class constructor, I wrote:
G4CMPVMeshInterpolator(const G4String& prefix)
: TetraStart(-1), savePrefix(prefix), TetraIdx(TetraIdxStore.Get()) {;}
Unfortunately, when I try running, I get inconsistent results or segfaults. One example just now reports the error deep in a vector evaluation:
(gdb) bt
#0 0x00002aaaaaedd2f7 in std::_Bit_reference::operator bool (
this=<optimized out>)
at /sw/eb/sw/GCCcore/12.2.0/include/c++/12.2.0/bits/stl_bvector.h:96
where my TetraIdx
index value is
(gdb) p TetraIdx
$2 = (G4double &) @0xc126e8: -1668109584
which is obviously nonsense (the index should run from 0 up to 1526086 for my test geometry).
I’ve probably got other problems that need fixing, but this is one I want to ask about. If I have multiple instances of the class, each one of which is shared across threads, does G4Cache::Get()
return a unique reference for each instance, or is there just one reference per thread?
Geant4 Version: 10.07.p04
Operating System: CentOS7
Compiler/Version: GCC 12.2.0
CMake Version: CMake 3.24.3