CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ConcurrentModuleTimer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Subsystem/Package
4 // Class : ConcurrentModuleTimer
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Chris Jones
10 // Created: Tue, 10 Dec 2013 21:16:00 GMT
11 //
12 #include <vector>
13 #include <atomic>
14 #include <chrono>
15 #include <iostream>
16 
24 
25 
26 namespace edm {
27  namespace service {
29  public:
32  //static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
33  private:
34  void start();
35  void stop();
36 
37  std::unique_ptr<std::atomic<std::chrono::high_resolution_clock::rep>[]> m_timeSums;
38  std::chrono::high_resolution_clock::time_point m_time;
39  unsigned int m_nTimeSums;
40  unsigned int m_nModules;
41  std::atomic<bool> m_spinLock;
43  };
44  }
45 }
46 
47 using namespace edm::service;
48 // system include files
49 
50 // user include files
51 
52 //
53 // constants, enums and typedefs
54 //
55 
56 //
57 // static data member definitions
58 //
59 
60 //
61 // constructors and destructor
62 //
64 m_time(),
65 m_nModules(0),
66 m_spinLock{false},
67 m_startedTiming(false)
68 {
69  iReg.watchPreModuleEvent([this](StreamContext const&, ModuleCallingContext const&){
70  start();
71  });
72  iReg.watchPostModuleEvent([this](StreamContext const&, ModuleCallingContext const&){
73  stop();
74  });
75 
76  iReg.watchPreModuleEventDelayedGet([this](StreamContext const&, ModuleCallingContext const& iContext){
77  if(iContext.state() == ModuleCallingContext::State::kRunning) {
78  stop();
79  }
80  });
81  iReg.watchPostModuleEventDelayedGet([this](StreamContext const&, ModuleCallingContext const& iContext){
82  if(iContext.state() == ModuleCallingContext::State::kRunning) {
83  start();
84  }
85  });
86 
87  iReg.watchPreallocate([this](edm::service::SystemBounds const& iBounds){
88  m_nTimeSums =iBounds.maxNumberOfThreads()+1;
89  m_timeSums.reset(new std::atomic<std::chrono::high_resolution_clock::rep>[m_nTimeSums]);
90  for(unsigned int i=0; i<m_nTimeSums;++i) {
91  m_timeSums[i]=0;
92  }
93  });
94 
95  iReg.watchPreSourceEvent([this](StreamID){
96  if(not m_startedTiming) {
98  m_startedTiming=true;
99  }
100  start();
101  });
102  iReg.watchPostSourceEvent([this](StreamID){
103  stop();
104  });
105 }
106 
108 
109  std::cout <<"Fraction of time running n Modules simultaneously"<<std::endl;
110  for (unsigned int i=0; i<m_nTimeSums; ++i) {
111  std::cout <<i<<" "<<m_timeSums[i]/double(m_timeSums[0])<<" "<<m_timeSums[i]<<std::endl;
112  }
113 
114 }
115 
116 // ConcurrentModuleTimer::ConcurrentModuleTimer(const ConcurrentModuleTimer& rhs)
117 // {
118 // // do actual copying here;
119 // }
120 
121 //
122 // assignment operators
123 //
124 // const ConcurrentModuleTimer& ConcurrentModuleTimer::operator=(const ConcurrentModuleTimer& rhs)
125 // {
126 // //An exception safe implementation is
127 // ConcurrentModuleTimer temp(rhs);
128 // swap(rhs);
129 //
130 // return *this;
131 // }
132 
133 //
134 // member functions
135 //
136 void
138 {
139  auto const newTime =std::chrono::high_resolution_clock::now();
140  std::chrono::high_resolution_clock::time_point oldTime;
141  bool expected = false;
142  unsigned int nModules;
143  while (not m_spinLock.compare_exchange_strong(expected,true,std::memory_order_acq_rel)){
144  expected = false;
145  }
146  {
147  oldTime = m_time;
148  m_time = newTime;
149  nModules = ++m_nModules;
150  m_spinLock.store(false,std::memory_order_release);
151  }
152  assert(nModules <m_nTimeSums);
153  auto diff = newTime - oldTime;
154  for(unsigned int i=0;i<nModules;++i) {
155  m_timeSums[i].fetch_add(diff.count());
156  }
157 }
158 
159 void
161 {
162  auto const newTime =std::chrono::high_resolution_clock::now();
163  std::chrono::high_resolution_clock::time_point oldTime;
164  bool expected = false;
165  unsigned int nModules;
166  while (not m_spinLock.compare_exchange_weak(expected,true,std::memory_order_acq_rel)){
167  expected = false;
168  }
169  {
170  oldTime = m_time;
171  m_time = newTime;
172  nModules = m_nModules--;
173  m_spinLock.store(false,std::memory_order_release);
174  }
175  assert(nModules <m_nTimeSums);
176  auto diff = newTime - oldTime;
177  for(unsigned int i=0;i<=nModules;++i) {
178  m_timeSums[i].fetch_add(diff.count());
179  }
180 }
181 
182 
183 //
184 // const member functions
185 //
186 
187 //
188 // static member functions
189 //
191 
unsigned int maxNumberOfThreads() const
Definition: SystemBounds.h:46
int i
Definition: DBlmapReader.cc:9
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
ConcurrentModuleTimer(edm::ParameterSet const &iConfig, edm::ActivityRegistry &iAR)
assert(m_qm.get())
std::chrono::high_resolution_clock::time_point m_time
#define DEFINE_FWK_SERVICE(type)
Definition: ServiceMaker.h:113
tuple cout
Definition: gather_cfg.py:121
std::unique_ptr< std::atomic< std::chrono::high_resolution_clock::rep >[]> m_timeSums