Exemplo n.º 1
0
Int_t mt001_fillHistos()
{

   // The first, fundamental operation to be performed in order to make ROOT
   // thread-aware.
   ROOT::EnableThreadSafety();

   // We define our work item
   auto workItem = [](UInt_t workerID) {
      // One generator, file and ntuple per worker
      TRandom3 workerRndm(workerID); // Change the seed
      TFile f(Form("myFile_%u.root", workerID), "RECREATE");
      TH1F h(Form("myHisto_%u", workerID), "The Histogram", 64, -4, 4);
      for (UInt_t i = 0; i < nNumbers; ++i) {
         h.Fill(workerRndm.Gaus());
      }
      h.Write();
   };

   // Create the collection which will hold the threads, our "pool"
   std::vector<std::thread> workers;

   // Fill the "pool" with workers
   for (auto workerID : ROOT::TSeqI(nWorkers)) {
      workers.emplace_back(workItem, workerID);
   }

   // Now join them
   for (auto && worker : workers) worker.join();

   return 0;
}
Exemplo n.º 2
0
Int_t mp001_fillHistos(UInt_t nWorkers = 4)
{

   // Total amount of numbers
   const UInt_t nNumbers = 20000000U;

   // We define our work item
   auto workItem = [nNumbers](UInt_t workerID) {
      // One generator, file and ntuple per worker
      TRandom3 workerRndm(workerID); // Change the seed
      TFile f(Form("myFile_%u.root", workerID), "RECREATE");
      TH1F h(Form("myHisto_%u", workerID), "The Histogram", 64, -4, 4);
      for (UInt_t i = 0; i < nNumbers; ++i) {
         h.Fill(workerRndm.Gaus());
      }
      h.Write();
      return 0;
   };

   // Create the pool of workers
   TProcPool workers(nWorkers);

   // Fill the pool with work
   std::forward_list<UInt_t> workerIDs(nWorkers);
   std::iota(std::begin(workerIDs), std::end(workerIDs), 0);
   workers.Map(workItem, workerIDs);

   return 0;

}
Exemplo n.º 3
0
Int_t mtbb101_fillNtuples()
{
   ROOT::EnableThreadSafety();
   // No nuisance for batch execution
   gROOT->SetBatch();

   // Perform the operation sequentially ---------------------------------------

   // Create a random generator and and Ntuple to hold the numbers
   TRandom3 rndm(1);
   TFile ofile("mp101_singleCore.root", "RECREATE");
   TNtuple randomNumbers("singleCore", "Random Numbers", "r");
   fillRandom(randomNumbers, rndm, nNumbers);
   randomNumbers.Write();
   ofile.Close();

   // We now go MP! ------------------------------------------------------------

   // We define our work item
   auto workItem = [](UInt_t workerID) {
      // One generator, file and ntuple per worker
      TRandom3 workerRndm(workerID); // Change the seed
      TFile ofile(Form("mp101_multiCore_%u.root", workerID), "RECREATE");
      TNtuple workerRandomNumbers("multiCore", "Random Numbers", "r");
      fillRandom(workerRandomNumbers, workerRndm, workSize);
      workerRandomNumbers.Write();
      return 0;
   };

   // Create the pool of workers
   ThreadPool pool(nThreads);

   // Fill the pool with work
   pool.Map(workItem, ROOT::TSeqI(nThreads));

   return 0;

}
Exemplo n.º 4
0
Int_t mt101_fillNtuples(UInt_t nWorkers = 4)
{

   // No nuisance for batch execution
   gROOT->SetBatch();

   // Total amount of numbers
   const UInt_t nNumbers = 20000000U;

   // A simple function to fill ntuples randomly

   auto fillRandom = [](TNtuple & ntuple, TRandom3 & rndm, UInt_t n) {
      for (UInt_t i = 0; i < n; ++i) ntuple.Fill(rndm.Gaus());
   };

   // Perform the operation sequentially ---------------------------------------

   // Create a random generator and and Ntuple to hold the numbers
   TRandom3 rndm(1);
   TFile ofile("mt101_singleCore.root", "RECREATE");
   TNtuple randomNumbers("singleCore", "Random Numbers", "r");

   // Now let's measure how much time we need to fill it up
   {
      TimerRAII t("Sequential execution");
      fillRandom(randomNumbers, rndm, nNumbers);
      randomNumbers.Write();
   }


   // We now go MT! ------------------------------------------------------------

   // The first, fundamental operation to be performed in order to make ROOT
   // thread-aware.
   ROOT::EnableThreadSafety();

   // We define our work item
   auto workItem = [&fillRandom](UInt_t workerID, UInt_t workSize) {
      // One generator, file and ntuple per worker
      TRandom3 workerRndm(workerID); // Change the seed
      TFile ofile(Form("mt101_multiCore_%u.root", workerID), "RECREATE");
      TNtuple workerRandomNumbers("multiCore", "Random Numbers", "r");
      fillRandom(workerRandomNumbers, workerRndm, workSize);
      workerRandomNumbers.Write();
   };

   // Create the collection which will hold the threads, our "pool"
   std::vector<std::thread> workers;

   // We measure time here as well
   {
      TimerRAII t("Parallel execution");

      // We split the work in equal parts
      const auto workSize = nNumbers / nWorkers;

      // Fill the "pool" with workers
      for (UInt_t workerID = 0; workerID < nWorkers; ++workerID) {
         workers.emplace_back(workItem, workerID, workSize);
      }

      // Now join them
      for (auto && worker : workers) worker.join();
   }

   return 0;

}