Fill n-tuples in distinct workers.
This tutorial illustrates the basics of how it's possible with ROOT to offload heavy operations on multiple threads and how it's possible to write simultaneously multiple files. The operation performed in this case is the creation of random gaussian numbers. NOTE: this code can be executed in a macro, ACLiC'ed or not, but not yet at the command line prompt.
class TimerRAII {
std::string fMeta;
public:
TimerRAII(const char *meta): fMeta(meta) {
fTimer.Start();
}
~TimerRAII() {
fTimer.Stop();
std::cout << fMeta << " - real time elapsed " << fTimer.RealTime() << "s" << std::endl;
}
};
{
const UInt_t nNumbers = 20000000U;
for (
UInt_t i = 0; i <
n; ++i) ntuple.
Fill(rndm.Gaus());
};
TFile ofile(
"mt101_singleCore.root",
"RECREATE");
TNtuple randomNumbers(
"singleCore",
"Random Numbers",
"r");
{
TimerRAII
t(
"Sequential execution");
randomNumbers.Write();
}
TFile ofile(
Form(
"mt101_multiCore_%u.root", workerID),
"RECREATE");
TNtuple workerRandomNumbers(
"multiCore",
"Random Numbers",
"r");
fillRandom(workerRandomNumbers, workerRndm, workSize);
workerRandomNumbers.Write();
};
std::vector<std::thread> workers;
{
TimerRAII
t(
"Parallel execution");
const auto workSize = nNumbers / nWorkers;
for (
UInt_t workerID = 0; workerID < nWorkers; ++workerID) {
workers.emplace_back(workItem, workerID, workSize);
}
for (auto && worker : workers) worker.join();
}
return 0;
}
- Author
- Danilo Piparo
Definition in file mt101_fillNtuples.C.