Side Effects of ROOT::EnableImplicitMT()?


ROOT Version: 6.18, 6.20, 6.22
Platform: CC7
Compiler: GCC10


Dear all,

I am currently testing multithreaded code on a platform with 96 cores. I use ROOT::TThreadedObject classes to parallelize access to histograms, which works fine with ROOT 6.22. However, with earlier versions I had issues pointing to a problem in the allocation of new slots:

Warning in <TThreadedObject::GetAtSlot>: Maximum number of slots reached.

 *** Break *** segmentation violation

Checking the code I saw that these parts have been reworked for 6.22, and there it works flawlessly. When browsing the ROOT code base for a possibility of allocating more slots for TThreadedObject right from the start I stumbled over ROOT::EnableImplicitMT() since its ROOT:: GetImplicitMTPoolSize() is set to the number of available threads and is used in the TThreadedObject constructor to allocate slots.

Calling this at start-up seems to solve my problem - but I was wondering if enabling this can have any side effects. Why is it not enabled by default?

Hello @simonspa,

In ROOT6, ROOT::EnableImplicitMT() must be called to enable support for threads. Doing so, also enables threading for some ROOT classes, e.g. RDataFrame or TTree. In some cases, this can be disabled per-object.

I hope this answers your question. If you have any other question, do not hesitate to reply back.

Cheers,
J.

Hi @jalopezg

Up till now I had only called ROOT::EnableThreadSafety(), which - according to the documentation - was the one call required for multithreading and thread safety. But from what you write there should be no negative/unexpected effects from also calling ROOT::EnableImplicitMT().

Is there some more detailed documentation around on how parallelized TTree access works? Or how threading can “be disabled per-object”?

Cheers,
SImon

Hello @simonspa,

Here you have some tutorials that illustrate how to use to use multi-threading.

Cheers,
J.

Hi @jalopezg

thanks for the link, but the examples were not really what I was looking for since I already have a large application with its own multithreading, so I can’t use ROOT’s internal and implicit parallelization. Thanks anyway, I think calling ROOT:EnableImplicitMT() does no harm in my use case.

/Simon

Hi @simonspa,

Sorry, I was trying to say that some of those examples illustrate some of your concerns, e.g. disable multi-threading for a spectific TTree instance.

For instance, the following code is part of the imt001_parBranchProcessing.C tutorial:

// IMT parallelisation can be disabled for a specific tree
tree->SetImplicitMT(false);

Cheers,
J.

Hi @jalopezg

okay, thanks! I’ll read through the examples, maybe I can find more to pick. :slight_smile:

/Simon

Hi,
I can probably add a bit more context: using TThreadedObject with more than 64 (if I remember correctly) threads before 6.22 is broken, it’s a bug that we fixed in 6.22.
Calling ROOT::EnableImplicitMT() does work around that bug, at least in v6.20. Another way is to manually set the value of TThreadedObject<Type>::fgMaxSlots to e.g. 96.
In 6.22, TThreadedObject just does the right thing.

As to what the side-effects of ROOT::EnableImplicitMT are: the docs list them all.

Hope this helps!
Enrico

Hi @eguiraud

great, thanks - I indeed found the hardcoded 64 threads in the pre-6.22 releases and traced back the workaround using EnableImplicitMT() form there. I can confirm that with 6.22 everything works flawlessly with 90 threads.

From what I see in the Doxygen list, nothing I have to worry about, so I can also leave it in for 6.22 and above without version check. :slight_smile:

Thanks!
Simon

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.