Skip to content

Wrapper class for TRef

Simon Spannagel requested to merge multithreading_wrapper into multithreading

This MR contains an attempt to work around the limitations we have to deal with when using TRef objects in massively multithreaded environments (c.f. https://root-forum.cern.ch/t/copying-trefs-and-accessing-tref-data-from-multiple-threads/29417/13).

The idea is relatively straightforward: we introduce a wrapper class which holds both the TRef object and an actual pointer. Whenever accessing the object we just return the pointer instead of querying the TRef object. The latter is only updated via contructor, set() member or the copy constructor used to store and load these objects to/from ROOT files. The pointer is stored via reinterpret_cast as uintptr_t type because ROOT's IO facilities do not seem to be capable of storing raw pointers to file.

This principle works fine and it has been demonstrated that in a "manual" approach (i.e. only loading/storing the TRef object with additional function calls when writing/reading to/from file) this works perfectly fine and scales without problem to 96 cores (tested on 2x AMD EPYC 7402). It however is not very nice from a usability perspective: analysis scripts would have to call the (non-intuitive) loadHistory() function when reading trees from file in order to be able to access the object history. Therefore this MR tries to integrate this behavior by overloading the copy constructor to avoid having to call additional member functions manually. However, only similar performance to the original code just using TRefs is achieved and I still have to understand why.

@kwolters ideas and/or comments would be very welcome.

The current code base contains some cout statements to better understand the lifetime of TRefs and Objects, for performance measurements these should of course be removed.

Edited by Simon Spannagel

Merge request reports