Is there non blocking equivalent to TMethodCall::Execute?

Hello,
In an old piece of code, we use in Atlas, there is an expression parser which uses MethodCall::Execute (e.g. “double ret; void *obj=…;m_method→Execute(obj,ret);")
to invoke methods of an object e.g. Muon::pt() const. Now this code was ported to a multi threaded environment and it performs horribly. Likely because MethodCall::Execute is protected internally by a TVirtualRWMutex::Lock. At least that is what shows up in profiles. There must be a better way, since RDataFrame does not suffer from this problem.

Do You have a recommendation for an improvement ?

Thank You Very much !
Götz

1 Like

Hi Götz,

Indeed, in presence of critical sections, MT code does not really scale.
And you are right, in presence of good designs, all the power of the hardware can be squeezed out!
Maybe to solve this issue well, maybe more context is needed.
Could you perhaps expose more details about your setup and what you want to achieve? There could be several options, depending on the situation.

Cheers,
Danilo

Hi Danilo,
for filtering we have a tool which filters events or objects based on expressions like muon.pt>20 && muon.eta>-2.4 && muon.eta<2.4. muon is a container name, pt a method of a container object, for which there is a TClass which knows about the methods e.g. pt and eta. The expression is parsed during initialization, and executed during runtime, the data is provided by the event store we use in atlas through handles. In principle TClass knows that the method exists, that the method has the correct signature i.e. double ()(const T *obj);. TClass does not know whether it would be safe to call the method in a MT context, I suppose, it only knows that the method is declared const. Anyway Execute is mutex protected. I did not profile this myself. So, I do not know exactly what was done. It is also possible that the VTune instrumentation makes these calls appear more expensive than they are without instrumentation. Anyway, the mutex protection seems unnecessary in this case, and since RDataFrame has the possibility to define “arbitrary” methods, which can be executed without such a penalty, there must be a better way.

Thanks !
Götz

P.S.”
To call e.g. pt we use once, I think, something like this
TMethodCall::InitWithPrototype (“….::Muon”, "pt", ““,false, kConversionMatch)
(btw. the false seems wrong … ). And then TMethodCall::Execute(obj, ret_dbl), for e.g. every event.