CMS 3D CMS Logo

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 
25 
26 namespace edm {
27  namespace service {
29  public:
32  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
33 
34  private:
35  void start();
36  void stop();
37 
38  bool trackModule(ModuleCallingContext const& iContext) const;
39  std::unique_ptr<std::atomic<std::chrono::high_resolution_clock::rep>[]> m_timeSums;
40  std::vector<std::string> m_modulesToExclude;
41  std::vector<unsigned int> m_excludedModuleIds;
42  std::chrono::high_resolution_clock::time_point m_time;
43  unsigned int m_nTimeSums = 0;
44  unsigned int m_nModules;
45  unsigned int m_maxNModules = 0;
46  const unsigned int m_padding;
47  std::atomic<bool> m_spinLock;
49  const bool m_excludeSource;
51  };
52  } // namespace service
53 } // namespace edm
54 
55 using namespace edm::service;
56 // system include files
57 
58 // user include files
59 
60 //
61 // constants, enums and typedefs
62 //
63 
64 //
65 // static data member definitions
66 //
67 
68 //
69 // constructors and destructor
70 //
72  : m_modulesToExclude(iConfig.getUntrackedParameter<std::vector<std::string>>("modulesToExclude")),
73  m_time(),
74  m_nModules(0),
75  m_padding(iConfig.getUntrackedParameter<unsigned int>("padding")),
76  m_spinLock{false},
77  m_startedTiming(false),
78  m_excludeSource(iConfig.getUntrackedParameter<bool>("excludeSource")),
79  m_trackGlobalBeginRun(iConfig.getUntrackedParameter<bool>("trackGlobalBeginRun")) {
80  if (not m_modulesToExclude.empty()) {
81  iReg.watchPreModuleConstruction([this](ModuleDescription const& iMod) {
82  for (auto const& name : m_modulesToExclude) {
83  if (iMod.moduleLabel() == name) {
84  m_excludedModuleIds.push_back(iMod.id());
85  break;
86  }
87  }
88  });
89  iReg.watchPreModuleEvent([this](StreamContext const&, ModuleCallingContext const& iContext) {
90  if (trackModule(iContext)) {
91  start();
92  }
93  });
94  iReg.watchPostModuleEvent([this](StreamContext const&, ModuleCallingContext const& iContext) {
95  if (trackModule(iContext)) {
96  stop();
97  }
98  });
99 
100  iReg.watchPreModuleEventDelayedGet([this](StreamContext const&, ModuleCallingContext const& iContext) {
101  if (trackModule(iContext)) {
102  if (iContext.state() == ModuleCallingContext::State::kRunning) {
103  stop();
104  }
105  }
106  });
107  iReg.watchPostModuleEventDelayedGet([this](StreamContext const&, ModuleCallingContext const& iContext) {
108  if (trackModule(iContext)) {
109  if (iContext.state() == ModuleCallingContext::State::kRunning) {
110  start();
111  }
112  }
113  });
114 
115  } else {
116  //apply to all modules so can use faster version
117  iReg.watchPreModuleEvent([this](StreamContext const&, ModuleCallingContext const&) { start(); });
118  iReg.watchPostModuleEvent([this](StreamContext const&, ModuleCallingContext const&) { stop(); });
119 
120  iReg.watchPreModuleEventDelayedGet([this](StreamContext const&, ModuleCallingContext const& iContext) {
121  if (iContext.state() == ModuleCallingContext::State::kRunning) {
122  stop();
123  }
124  });
125  iReg.watchPostModuleEventDelayedGet([this](StreamContext const&, ModuleCallingContext const& iContext) {
126  if (iContext.state() == ModuleCallingContext::State::kRunning) {
127  start();
128  }
129  });
130  if (m_trackGlobalBeginRun) {
131  iReg.watchPreModuleGlobalBeginRun([this](GlobalContext const&, ModuleCallingContext const&) {
132  if (not m_startedTiming) {
134  m_startedTiming = true;
135  }
136 
137  start();
138  });
139  iReg.watchPostModuleGlobalBeginRun([this](GlobalContext const&, ModuleCallingContext const&) { stop(); });
140  }
141  }
142 
143  iReg.watchPreallocate([this](edm::service::SystemBounds const& iBounds) {
144  m_nTimeSums = iBounds.maxNumberOfThreads() + 1 + m_padding;
145  m_timeSums.reset(new std::atomic<std::chrono::high_resolution_clock::rep>[m_nTimeSums]);
146  for (unsigned int i = 0; i < m_nTimeSums; ++i) {
147  m_timeSums[i] = 0;
148  }
149  });
150 
151  iReg.watchPreSourceEvent([this](StreamID) {
152  if (not m_startedTiming) {
154  m_startedTiming = true;
155  }
156  if (not m_excludeSource) {
157  start();
158  }
159  });
160  if (not m_excludeSource) {
161  iReg.watchPostSourceEvent([this](StreamID) { stop(); });
162  }
163 }
164 
166  std::cout << "Maximum concurrent running modules: " << m_maxNModules << std::endl;
167  std::cout << "Fraction of time running n Modules simultaneously" << std::endl;
168  for (unsigned int i = 0; i < m_nTimeSums; ++i) {
169  std::cout << i << " " << m_timeSums[i] / double(m_timeSums[0]) << " " << m_timeSums[i] << std::endl;
170  }
171 }
172 
173 // ConcurrentModuleTimer::ConcurrentModuleTimer(const ConcurrentModuleTimer& rhs)
174 // {
175 // // do actual copying here;
176 // }
177 
178 //
179 // assignment operators
180 //
181 // const ConcurrentModuleTimer& ConcurrentModuleTimer::operator=(const ConcurrentModuleTimer& rhs)
182 // {
183 // //An exception safe implementation is
184 // ConcurrentModuleTimer temp(rhs);
185 // swap(rhs);
186 //
187 // return *this;
188 // }
189 
190 //
191 // member functions
192 //
194  auto const newTime = std::chrono::high_resolution_clock::now();
195  std::chrono::high_resolution_clock::time_point oldTime;
196  bool expected = false;
197  unsigned int nModules;
198  while (not m_spinLock.compare_exchange_strong(expected, true, std::memory_order_acq_rel)) {
199  expected = false;
200  }
201  {
202  oldTime = m_time;
203  m_time = newTime;
204  nModules = ++m_nModules;
205  if (nModules > m_maxNModules) {
206  m_maxNModules = nModules;
207  }
208  m_spinLock.store(false, std::memory_order_release);
209  }
210  assert(nModules < m_nTimeSums);
211  auto diff = newTime - oldTime;
212  for (unsigned int i = 0; i < nModules; ++i) {
213  m_timeSums[i].fetch_add(diff.count());
214  }
215 }
216 
218  auto const newTime = std::chrono::high_resolution_clock::now();
219  std::chrono::high_resolution_clock::time_point oldTime;
220  bool expected = false;
221  unsigned int nModules;
222  while (not m_spinLock.compare_exchange_weak(expected, true, std::memory_order_acq_rel)) {
223  expected = false;
224  }
225  {
226  oldTime = m_time;
227  m_time = newTime;
228  nModules = m_nModules--;
229  m_spinLock.store(false, std::memory_order_release);
230  }
231  assert(nModules < m_nTimeSums);
232  auto diff = newTime - oldTime;
233  for (unsigned int i = 0; i <= nModules; ++i) {
234  m_timeSums[i].fetch_add(diff.count());
235  }
236 }
237 
238 //
239 // const member functions
240 //
242  auto modId = iContext.moduleDescription()->id();
243  for (auto const id : m_excludedModuleIds) {
244  if (modId == id) {
245  return false;
246  }
247  }
248  return true;
249 }
250 
251 //
252 // static member functions
253 //
256  desc.addUntracked<std::vector<std::string>>("modulesToExclude", std::vector<std::string>{})
257  ->setComment("Module labels to exclude from the timing measurements");
258  desc.addUntracked<bool>("excludeSource", false)->setComment("Exclude the time the source is running");
259  desc.addUntracked<unsigned int>("padding", 0)
260  ->setComment(
261  "[Expert use only] Extra possible concurrent modules beyond thread count.\n Only useful in debugging "
262  "possible framework scheduling problems.");
263  desc.addUntracked<bool>("trackGlobalBeginRun", false)
264  ->setComment("Check for concurrent modules during global begin run");
265  descriptions.add("ConcurrentModuleTimer", desc);
266 }
267 
ConfigurationDescriptions.h
change_name.diff
diff
Definition: change_name.py:13
edm::ModuleDescription::moduleLabel
std::string const & moduleLabel() const
Definition: ModuleDescription.h:43
service
Definition: service.py:1
ModuleCallingContext.h
mps_fire.i
i
Definition: mps_fire.py:428
edm::service::ConcurrentModuleTimer::m_modulesToExclude
std::vector< std::string > m_modulesToExclude
Definition: ConcurrentModuleTimer.cc:40
edm::service::ConcurrentModuleTimer::m_nModules
unsigned int m_nModules
Definition: ConcurrentModuleTimer.cc:44
submitPVValidationJobs.now
now
Definition: submitPVValidationJobs.py:639
edm::service::ConcurrentModuleTimer::m_trackGlobalBeginRun
const bool m_trackGlobalBeginRun
Definition: ConcurrentModuleTimer.cc:50
edm
HLT enums.
Definition: AlignableModifier.h:19
gather_cfg.cout
cout
Definition: gather_cfg.py:144
edm::ParameterSetDescription
Definition: ParameterSetDescription.h:52
DEFINE_FWK_SERVICE
#define DEFINE_FWK_SERVICE(type)
Definition: ServiceMaker.h:105
edm::service::ConcurrentModuleTimer::m_timeSums
std::unique_ptr< std::atomic< std::chrono::high_resolution_clock::rep >[]> m_timeSums
Definition: ConcurrentModuleTimer.cc:39
cms::cuda::assert
assert(be >=bs)
edm::service::ConcurrentModuleTimer::m_excludedModuleIds
std::vector< unsigned int > m_excludedModuleIds
Definition: ConcurrentModuleTimer.cc:41
edm::ModuleCallingContext::moduleDescription
ModuleDescription const * moduleDescription() const
Definition: ModuleCallingContext.h:50
edm::service::ConcurrentModuleTimer::m_maxNModules
unsigned int m_maxNModules
Definition: ConcurrentModuleTimer.cc:45
edm::service::ConcurrentModuleTimer::m_spinLock
std::atomic< bool > m_spinLock
Definition: ConcurrentModuleTimer.cc:47
edm::ModuleDescription
Definition: ModuleDescription.h:21
ModuleDescription.h
ActivityRegistry.h
edm::service::ConcurrentModuleTimer::m_nTimeSums
unsigned int m_nTimeSums
Definition: ConcurrentModuleTimer.cc:43
edm::ConfigurationDescriptions::add
void add(std::string const &label, ParameterSetDescription const &psetDescription)
Definition: ConfigurationDescriptions.cc:57
edm::service::ConcurrentModuleTimer::m_padding
const unsigned int m_padding
Definition: ConcurrentModuleTimer.cc:46
edm::service::ConcurrentModuleTimer::m_time
std::chrono::high_resolution_clock::time_point m_time
Definition: ConcurrentModuleTimer.cc:42
edm::ActivityRegistry
Definition: ActivityRegistry.h:133
edm::service::ConcurrentModuleTimer::stop
void stop()
Definition: ConcurrentModuleTimer.cc:217
ServiceMaker.h
edm::ConfigurationDescriptions
Definition: ConfigurationDescriptions.h:28
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
edm::service::SystemBounds
Definition: SystemBounds.h:29
edm::ParameterSet
Definition: ParameterSet.h:47
edm::service::SystemBounds::maxNumberOfThreads
unsigned int maxNumberOfThreads() const
Definition: SystemBounds.h:38
edm::service::ConcurrentModuleTimer::fillDescriptions
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
Definition: ConcurrentModuleTimer.cc:254
createfilelist.int
int
Definition: createfilelist.py:10
edm::service::ConcurrentModuleTimer
Definition: ConcurrentModuleTimer.cc:28
edm::service::ConcurrentModuleTimer::~ConcurrentModuleTimer
~ConcurrentModuleTimer()
Definition: ConcurrentModuleTimer.cc:165
trackerHitRTTI::vector
Definition: trackerHitRTTI.h:21
edm::service
Definition: TFileService.h:95
edm::service::ConcurrentModuleTimer::start
void start()
Definition: ConcurrentModuleTimer.cc:193
submitPVResolutionJobs.desc
string desc
Definition: submitPVResolutionJobs.py:251
std
Definition: JetResolutionObject.h:76
edm::service::ConcurrentModuleTimer::m_startedTiming
bool m_startedTiming
Definition: ConcurrentModuleTimer.cc:48
Skims_PA_cff.name
name
Definition: Skims_PA_cff.py:17
edm::service::ConcurrentModuleTimer::ConcurrentModuleTimer
ConcurrentModuleTimer(edm::ParameterSet const &iConfig, edm::ActivityRegistry &iAR)
Definition: ConcurrentModuleTimer.cc:71
command_line.start
start
Definition: command_line.py:167
CPUTimer.h
ParameterSet.h
SystemBounds.h
edm::service::ConcurrentModuleTimer::m_excludeSource
const bool m_excludeSource
Definition: ConcurrentModuleTimer.cc:49
edm::ModuleDescription::id
unsigned int id() const
Definition: ModuleDescription.h:46
edm::ModuleCallingContext::State::kRunning
edm::ModuleCallingContext
Definition: ModuleCallingContext.h:29
edm::service::ConcurrentModuleTimer::trackModule
bool trackModule(ModuleCallingContext const &iContext) const
Definition: ConcurrentModuleTimer.cc:241