Message: Re: FieldManager handling Not Logged In (login)
 Next-in-Thread Next-in-Thread
 Next-in-Forum Next-in-Forum

Feedback Re: FieldManager handling 

Forum: Multithreading
Re: None FieldManager handling (Andrea Di Simone)
Re: Feedback Re: FieldManager handling (Andrea Dotti)
Re: None Re: FieldManager handling (Andrea Di Simone)
Re: Warning Re: FieldManager handling (Andrea Dotti)
Re: None Re: FieldManager handling (Andrea Di Simone)
Date: 06 Nov, 2012
From: Andrea Dotti <Andrea Dotti>

Hi Andrea, Very good point!

there is a trick under the hood that makes all this possible. It is not very simple, but I will try to clarify the mechanism involved. Please consider that I am not the author of this (for me very intelligent) mechanism, and I give only my interpretation based on code inspection and my knowledge of G4.

Let't take the case of the FieldManager that is attached to the logical volume (but it's the same everywhere a similar problem arise). You want to obtain the following: Have only one (shared) instance of the logical volume and have several instances of FieldManager attached to it, one for each thread. As an addendum you need to have many G4LogicalVolume instances each one with a possibly different G4FieldManager. Thus what you want to obtain is to have each created G4LogicalVolume shared among threads, but each thread should have its own G4FieldManager data member.

I will try now to simplify, but imagine the following:

- In the sequential version of G4 the class G4LogicalVolume has a data member of type: G4FieldManager* (you can check yourself here:

- In the MT version of the code the same pointer has to be changed. As a first step you could just change it to be static __thread G4FieldManager* and you would almost obtain what is needed.

- Almost because in this way ALL G4LogicalVolume instances of the same thread would share the same G4FieldManager that of course is not what you want

- The second change is to make the data member from a pointer to an "array" of pointers: static __thread SomeKindOfArray<G4FieldManager*>. The "index" of this array is the instance number of G4LogicalVolume. For example the very first time that you create a G4LogicalVolume this one has an index 0, the second time the index is one etc.

- Now each instance of G4LogicalVolume uses its "instance number" to access the static array and get the correct G4FieldManager. But since the static is also __thread, each thread has its own array.

- So actually when in your code you use the method: G4LogicalVolume::SetFieldManager( myfield ) that originally is simply { fieldManager = myfield;} in G4MT actually you are doing something like: { theArrayOfFiledsOfThisThread[ theInstanceID ] = myfield; }

- Boom! The magic is done...

In this description I have probably simplified the system (the array part), but if you now look at the G4LogicalVolume header file of the MT version you have, you will notice several differences, in particular you will notice that the G4FieldManager* data member is now part of a separate class that than is used to create an instance of a (per-thread) "manager". This objects holds the logic of the "array" described in the simplified description above.

Note that all this is needed because C++ thread-local-storage __thread keyword only works in few cases ( The future could be simpler, if GCC 4.8 (2013?) will maintains its promise about thread_local implementation: (and search for thread_local), even if C++11 standard is not completely clear on this: (at least to a fast read).

Hope this helps in clarifying a bit, Andrea

Inline Depth:
 1 1
 All All
Outline Depth:
 1 1
 2 2
 All All
Add message: (add)

1 None: Re: FieldManager handling   (Andrea Di Simone - 07 Nov, 2012)
 Add Message Add Message
to: "Re: FieldManager handling"

 Subscribe Subscribe

This site runs SLAC HyperNews version 1.11-slac-98, derived from the original HyperNews