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?
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.
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”?
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.
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.
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.