//test.cpp #include #include #include #include "TRandom3.h" #include "TCanvas.h" #include "ROOT/RDataFrame.hxx" /* struct RandomEngines{ RandomEngines(){ //Assuming you have <= 64 cores for (int i=0; i<64; i++) engines.push_back( TRandom3( rd() ) ); } std::vector< TRandom3 > engines; // for random seeding of several random engines std::random_device rd; }; RandomEngines engines;*/ TRandom3 rg; double GetRNG() { return rg.Gaus(); } double GetRNG_threadlocal_engine() { static thread_local TRandom3 r3(std::hash{}(std::this_thread::get_id())); /* you can also use rand() as seed instead*/ return r3.Gaus(); } double GetRNGSlot() { static thread_local TRandom3 r3; return r3.Gaus(); } void test(){ auto* c1 = new TCanvas("c1", "c1", 1500, 500); c1->Divide(3, 1); ROOT::DisableImplicitMT(); auto df1 = ROOT::RDataFrame(90000000).Define("x", GetRNG); auto h1 = df1.Histo1D({"h1", "single core", 1000, -4, 4}, {"x"}); c1->cd(1); h1->DrawClone(); ROOT::EnableImplicitMT(16); auto df3 = ROOT::RDataFrame(90000000).Define("x", GetRNG); auto df4 = ROOT::RDataFrame(90000000).Define("x", GetRNG_threadlocal_engine); auto h3 = df3.Histo1D({"h3", "single random engine", 1000, -4, 4}, {"x"}); auto h4 = df4.Histo1D({"h4", "threadlocal engines", 1000, -4, 4}, {"x"}); c1->cd(2); h3->DrawClone(); c1->cd(3); h4->DrawClone(); std::cout<GetMean()<<" +- "<GetStdDev()<GetMean()<<" +- "<GetStdDev()<GetMean()<<" +- "<GetStdDev()<