Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
concurrentfill.cxx
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_v7
3 ///
4 /// \macro_code
5 ///
6 /// \date 2015-07-09
7 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
8 /// is welcome!
9 /// \author Axel Naumann <axel@cern.ch>
10 
11 /*************************************************************************
12  * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
13  * All rights reserved. *
14  * *
15  * For the licensing terms see $ROOTSYS/LICENSE. *
16  * For the list of contributors see $ROOTSYS/README/CREDITS. *
17  *************************************************************************/
18 
19 #include "ROOT/RHist.hxx"
21 
22 #include <iostream>
23 #include <future>
24 #include <random>
25 
26 using namespace ROOT;
27 
28 double wasteCPUTime(std::mt19937 &gen)
29 {
30  // Simulate number crunching through gen and ridiculous num bits
31  return std::generate_canonical<double, 100>(gen) + std::generate_canonical<double, 100>(gen) +
32  std::generate_canonical<double, 100>(gen) + std::generate_canonical<double, 100>(gen) +
33  std::generate_canonical<double, 100>(gen);
34 }
35 
36 using Filler_t = Experimental::RHistConcurrentFiller<Experimental::RH2D, 1024>;
37 
38 /// This function is called within each thread: it spends some CPU time and then
39 /// fills a number into the histogram, through the Filler_t. This is repeated
40 /// several times.
41 void theTask(Filler_t filler)
42 {
43  std::mt19937 gen;
44 
45  for (int i = 0; i < 3000000; ++i)
46  filler.Fill({wasteCPUTime(gen), wasteCPUTime(gen)});
47 }
48 
49 /// This example fills a histogram concurrently, from several threads.
50 void concurrentHistFill(Experimental::RH2D &hist)
51 {
52  // RHistConcurrentFillManager allows multiple threads to fill the histogram
53  // concurrently.
54  //
55  // Details: each thread's Fill() calls are buffered. once the buffer is full,
56  // the RHistConcurrentFillManager locks and flushes the buffer into the
57  // histogram.
58  Experimental::RHistConcurrentFillManager<Experimental::RH2D> fillMgr(hist);
59 
60  std::array<std::thread, 8> threads;
61 
62  // Let the threads fill the histogram concurrently.
63  for (auto &thr: threads) {
64  // Each thread calls fill(), passing a dedicated filler per thread.
65  thr = std::thread(theTask, fillMgr.MakeFiller());
66  }
67 
68  // Join them.
69  for (auto &thr: threads)
70  thr.join();
71 }
72 
73 void concurrentfill()
74 {
75  // This histogram will be filled from several threads.
76  Experimental::RH2D hist{{100, 0., 1.}, {{0., 1., 2., 3., 10.}}};
77 
78  concurrentHistFill(hist);
79 
80  std::cout << hist.GetEntries() << '\n';
81 }