Processor Counter Monitor
width_extender.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 // Copyright (c) 2009-2018, Intel Corporation
3 // written by Roman Dementiev
4 // Austen Ott
5 
6 #ifndef WIDTH_EXTENDER_HEADER_
7 #define WIDTH_EXTENDER_HEADER_
8 
13 #include <stdlib.h>
14 #include "cpucounters.h"
15 #include "utils.h"
16 #include "bw.h"
17 #include "mutex.h"
18 #include <memory>
19 #ifndef _MSC_VER
20 // the header can not be included into code using CLR
21 #include <thread>
22 #else
23 namespace std {
24  class thread;
25  }
26 #endif
27 
28 namespace pcm {
29 
31 {
32 public:
34  {
35  virtual uint64 operator () () = 0;
36  virtual ~AbstractRawCounter() { }
37  };
38 
40  {
41  std::shared_ptr<SafeMsrHandle> msr;
42  uint64 msr_addr;
43  MsrHandleCounter(std::shared_ptr<SafeMsrHandle> msr_, uint64 msr_addr_) : msr(msr_), msr_addr(msr_addr_) { }
44  uint64 operator () ()
45  {
46  uint64 value = 0;
47  msr->read(msr_addr, &value);
48  return value;
49  }
50  };
51 
52  template <uint64 (FreeRunningBWCounters::*F)()>
54  {
55  std::shared_ptr<FreeRunningBWCounters> clientBW;
56  ClientImcCounter(std::shared_ptr<FreeRunningBWCounters> clientBW_) : clientBW(clientBW_) { }
57  uint64 operator () () { return (clientBW.get()->*F)(); }
58  };
59 
65 
67  {
68  std::shared_ptr<SafeMsrHandle> msr;
69  MBLCounter(std::shared_ptr<SafeMsrHandle> msr_) : msr(msr_) { }
70  uint64 operator () ()
71  {
72  msr->lock();
73  uint64 event = 3; // L3 Local External Bandwidth
74  uint64 msr_qm_evtsel = 0, value = 0;
75  msr->read(IA32_QM_EVTSEL, &msr_qm_evtsel);
76  //std::cout << "MBLCounter reading IA32_QM_EVTSEL 0x"<< std::hex << msr_qm_evtsel << std::dec << "\n";
77  msr_qm_evtsel &= 0xfffffffffffffff0ULL;
78  msr_qm_evtsel |= event & ((1ULL << 8) - 1ULL);
79  //std::cout << "MBL event " << msr_qm_evtsel << "\n";
80  //std::cout << "MBLCounter writing IA32_QM_EVTSEL 0x"<< std::hex << msr_qm_evtsel << std::dec << "\n";
81  msr->write(IA32_QM_EVTSEL, msr_qm_evtsel);
82  msr->read(IA32_QM_CTR, &value);
83  //std::cout << "MBLCounter reading IA32_QM_CTR "<< std::dec << value << std::dec << "\n";
84  msr->unlock();
85  return value;
86  }
87  };
88 
90  {
91  std::shared_ptr<SafeMsrHandle> msr;
92  MBTCounter(std::shared_ptr<SafeMsrHandle> msr_) : msr(msr_) { }
93  uint64 operator () ()
94  {
95  msr->lock();
96  uint64 event = 2; // L3 Total External Bandwidth
97  uint64 msr_qm_evtsel = 0, value = 0;
98  msr->read(IA32_QM_EVTSEL, &msr_qm_evtsel);
99  //std::cout << "MBTCounter reading IA32_QM_EVTSEL 0x"<< std::hex << msr_qm_evtsel << std::dec << "\n";
100  msr_qm_evtsel &= 0xfffffffffffffff0ULL;
101  msr_qm_evtsel |= event & ((1ULL << 8) - 1ULL);
102  //std::cout << "MBR event " << msr_qm_evtsel << "\n";
103  //std::cout << "MBTCounter writing IA32_QM_EVTSEL 0x"<< std::hex << msr_qm_evtsel << std::dec << "\n";
104  msr->write(IA32_QM_EVTSEL, msr_qm_evtsel);
105  msr->read(IA32_QM_CTR, &value);
106  //std::cout << "MBTCounter reading IA32_QM_CTR "<< std::dec << value << std::dec << "\n";
107  msr->unlock();
108  return value;
109  }
110  };
111 
112 private:
113  std::thread * UpdateThread;
114 
115  Mutex CounterMutex;
116 
117  AbstractRawCounter * raw_counter;
118  uint64 extended_value;
119  uint64 last_raw_value;
120  uint64 counter_width;
121  uint32 watchdog_delay_ms;
122 
123  CounterWidthExtender(); // forbidden
125  CounterWidthExtender & operator = (const CounterWidthExtender &); // forbidden
126 
127 
128  uint64 internal_read()
129  {
130  uint64 result = 0, new_raw_value = 0;
131  CounterMutex.lock();
132 
133  new_raw_value = (*raw_counter)();
134  if (new_raw_value < last_raw_value)
135  {
136  extended_value += ((1ULL << counter_width) - last_raw_value) + new_raw_value;
137  }
138  else
139  {
140  extended_value += (new_raw_value - last_raw_value);
141  }
142 
143  last_raw_value = new_raw_value;
144 
145  result = extended_value;
146 
147  CounterMutex.unlock();
148  return result;
149  }
150 
151 public:
152 
153  CounterWidthExtender(AbstractRawCounter * raw_counter_, uint64 counter_width_, uint32 watchdog_delay_ms_);
154  virtual ~CounterWidthExtender();
155 
156  uint64 read() // read extended value
157  {
158  return internal_read();
159  }
160  void reset()
161  {
162  CounterMutex.lock();
163  extended_value = last_raw_value = (*raw_counter)();
164  CounterMutex.unlock();
165  }
166 };
167 
168 } // namespace pcm
169 
170 #endif
Definition: width_extender.h:30
Definition: mutex.h:14
Some common utility routines.
Definition: width_extender.h:39
Definition: width_extender.h:89
Main CPU counters header.
Definition: bw.cpp:12
Definition: width_extender.h:53
Definition: width_extender.h:33
Definition: width_extender.h:66
Interfaces to access free-running bandwidth counters.