gem5  v22.1.0.0
AddressProfiler.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met: redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer;
9  * redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution;
12  * neither the name of the copyright holders nor the names of its
13  * contributors may be used to endorse or promote products derived from
14  * this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
30 
31 #include <vector>
32 
33 #include "base/bitfield.hh"
34 #include "base/stl_helpers.hh"
36 #include "mem/ruby/protocol/RubyRequest.hh"
37 
38 namespace gem5
39 {
40 
41 namespace ruby
42 {
43 
45 
46 using gem5::stl_helpers::operator<<;
47 
48 // Helper functions
51 {
52  // we create a static default object here that is used to insert
53  // since the insertion will create a copy of the object in the
54  // process. Perhaps this is optimizing early, but it doesn't seem
55  // like it could hurt.
56  static const AccessTraceForAddress dflt;
57 
59  record_map.insert(std::make_pair(addr, dflt));
60  AddressMap::iterator i = r.first;
61  AccessTraceForAddress &access_trace = i->second;
62  if (r.second) {
63  // there was nothing there and the insert succeed, so we need
64  // to actually set the address.
65  access_trace.setAddress(addr);
66  }
67 
68  return access_trace;
69 }
70 
71 void
72 printSorted(std::ostream& out, int num_of_sequencers,
73  const AddressMap &record_map, std::string description,
74  Profiler *profiler)
75 {
76  const int records_printed = 100;
77 
78  uint64_t misses = 0;
80 
81  AddressMap::const_iterator i = record_map.begin();
82  AddressMap::const_iterator end = record_map.end();
83  for (; i != end; ++i) {
84  const AccessTraceForAddress* record = &i->second;
85  misses += record->getTotal();
86  sorted.push_back(record);
87  }
88  sort(sorted.begin(), sorted.end(), AccessTraceForAddress::less_equal);
89 
90  out << "Total_entries_" << description << ": " << record_map.size()
91  << std::endl;
92  if (profiler->getAllInstructions()) {
93  out << "Total_Instructions_" << description << ": " << misses
94  << std::endl;
95  } else {
96  out << "Total_data_misses_" << description << ": " << misses
97  << std::endl;
98  }
99 
100  out << "total | load store atomic | user supervisor | sharing | touched-by"
101  << std::endl;
102 
103  Histogram remaining_records(1, 100);
104  Histogram all_records(1, 100);
105  Histogram remaining_records_log(-1);
106  Histogram all_records_log(-1);
107 
108  // Allows us to track how many lines where touched by n processors
109  std::vector<int64_t> m_touched_vec;
110  std::vector<int64_t> m_touched_weighted_vec;
111  m_touched_vec.resize(num_of_sequencers+1);
112  m_touched_weighted_vec.resize(num_of_sequencers+1);
113  for (int j = 0; j < m_touched_vec.size(); j++) {
114  m_touched_vec[j] = 0;
115  m_touched_weighted_vec[j] = 0;
116  }
117 
118  int counter = 0;
119  int max = sorted.size();
120  while (counter < max && counter < records_printed) {
121  const AccessTraceForAddress* record = sorted[counter];
122  double percent = 100.0 * (record->getTotal() / double(misses));
123  out << description << " | " << percent << " % " << *record
124  << std::endl;
125  all_records.add(record->getTotal());
126  all_records_log.add(record->getTotal());
127  counter++;
128  m_touched_vec[record->getTouchedBy()]++;
129  m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
130  }
131 
132  while (counter < max) {
133  const AccessTraceForAddress* record = sorted[counter];
134  all_records.add(record->getTotal());
135  remaining_records.add(record->getTotal());
136  all_records_log.add(record->getTotal());
137  remaining_records_log.add(record->getTotal());
138  m_touched_vec[record->getTouchedBy()]++;
139  m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
140  }
141  out << std::endl;
142  out << "all_records_" << description << ": "
143  << all_records << std::endl
144  << "all_records_log_" << description << ": "
145  << all_records_log << std::endl
146  << "remaining_records_" << description << ": "
147  << remaining_records << std::endl
148  << "remaining_records_log_" << description << ": "
149  << remaining_records_log << std::endl
150  << "touched_by_" << description << ": "
151  << m_touched_vec << std::endl
152  << "touched_by_weighted_" << description << ": "
153  << m_touched_weighted_vec << std::endl
154  << std::endl;
155 }
156 
157 AddressProfiler::AddressProfiler(int num_of_sequencers, Profiler *profiler)
158  : m_profiler(profiler)
159 {
160  m_num_of_sequencers = num_of_sequencers;
161  clearStats();
162 }
163 
165 {
166 }
167 
168 void
170 {
171  m_hot_lines = hot_lines;
172 }
173 
174 void
176 {
177  m_all_instructions = all_instructions;
178 }
179 
180 void
181 AddressProfiler::printStats(std::ostream& out) const
182 {
183  if (m_hot_lines) {
184  out << std::endl;
185  out << "AddressProfiler Stats" << std::endl;
186  out << "---------------------" << std::endl;
187 
188  out << std::endl;
189  out << "sharing_misses: " << m_sharing_miss_counter << std::endl;
190  out << "getx_sharing_histogram: " << m_getx_sharing_histogram
191  << std::endl;
192  out << "gets_sharing_histogram: " << m_gets_sharing_histogram
193  << std::endl;
194 
195  out << std::endl;
196  out << "Hot Data Blocks" << std::endl;
197  out << "---------------" << std::endl;
198  out << std::endl;
200  "block_address", m_profiler);
201 
202  out << std::endl;
203  out << "Hot MacroData Blocks" << std::endl;
204  out << "--------------------" << std::endl;
205  out << std::endl;
207  "macroblock_address", m_profiler);
208 
209  out << "Hot Instructions" << std::endl;
210  out << "----------------" << std::endl;
211  out << std::endl;
213  "pc_address", m_profiler);
214  }
215 
216  if (m_all_instructions) {
217  out << std::endl;
218  out << "All Instructions Profile:" << std::endl;
219  out << "-------------------------" << std::endl;
220  out << std::endl;
222  "pc_address", m_profiler);
223  out << std::endl;
224  }
225 
226  if (m_retryProfileHisto.size() > 0) {
227  out << "Retry Profile" << std::endl;
228  out << "-------------" << std::endl;
229  out << std::endl;
230  out << "retry_histogram_absolute: " << m_retryProfileHisto
231  << std::endl;
232  out << "retry_histogram_write: " << m_retryProfileHistoWrite
233  << std::endl;
234  out << "retry_histogram_read: " << m_retryProfileHistoRead
235  << std::endl;
236 
237  out << "retry_histogram_percent: ";
239  out << std::endl;
240 
242  "block_address", m_profiler);
243  out << std::endl;
244  }
245 }
246 
247 void
249 {
250  // Clear the maps
252  m_dataAccessTrace.clear();
253  m_macroBlockAccessTrace.clear();
255  m_retryProfileMap.clear();
261 }
262 
263 void
265  const Set& owner, const Set& sharers,
266  NodeID requestor)
267 {
268  Set indirection_set;
269  indirection_set.addSet(sharers);
270  indirection_set.addSet(owner);
271  indirection_set.remove(requestor);
272  int num_indirections = indirection_set.count();
273 
274  m_getx_sharing_histogram.add(num_indirections);
275  bool indirection_miss = (num_indirections > 0);
276 
277  addTraceSample(datablock, PC, RubyRequestType_ST, RubyAccessMode(0),
278  requestor, indirection_miss);
279 }
280 
281 void
283  const Set& owner, const Set& sharers,
284  NodeID requestor)
285 {
286  Set indirection_set;
287  indirection_set.addSet(owner);
288  indirection_set.remove(requestor);
289  int num_indirections = indirection_set.count();
290 
291  m_gets_sharing_histogram.add(num_indirections);
292  bool indirection_miss = (num_indirections > 0);
293 
294  addTraceSample(datablock, PC, RubyRequestType_LD, RubyAccessMode(0),
295  requestor, indirection_miss);
296 }
297 
298 void
300  RubyRequestType type,
301  RubyAccessMode access_mode, NodeID id,
302  bool sharing_miss)
303 {
304  if (m_all_instructions) {
305  if (sharing_miss) {
307  }
308 
309  // record data address trace info
310  data_addr = makeLineAddress(data_addr);
312  update(type, access_mode, id, sharing_miss);
313 
314  // record macro data address trace info
315 
316  // 6 for datablock, 4 to make it 16x more coarse
317  Addr macro_addr = mbits<Addr>(data_addr, 63, 10);
319  update(type, access_mode, id, sharing_miss);
320 
321  // record program counter address trace info
323  update(type, access_mode, id, sharing_miss);
324  }
325 
326  if (m_all_instructions) {
327  // This code is used if the address profiler is an
328  // all-instructions profiler record program counter address
329  // trace info
331  update(type, access_mode, id, sharing_miss);
332  }
333 }
334 
335 void
336 AddressProfiler::profileRetry(Addr data_addr, AccessType type, int count)
337 {
339  if (type == AccessType_Read) {
341  } else {
343  }
344  if (count > 1) {
346  }
347 }
348 
349 } // namespace ruby
350 } // namespace gem5
static bool less_equal(const AccessTraceForAddress *n1, const AccessTraceForAddress *n2)
void profileGetX(Addr datablock, Addr PC, const Set &owner, const Set &sharers, NodeID requestor)
void setHotLines(bool hot_lines)
AddressProfiler(int num_of_sequencers, Profiler *profiler)
void profileRetry(Addr data_addr, AccessType type, int count)
std::unordered_map< Addr, AccessTraceForAddress > AddressMap
void addTraceSample(Addr data_addr, Addr pc_addr, RubyRequestType type, RubyAccessMode access_mode, NodeID id, bool sharing_miss)
void setAllInstructions(bool all_instructions)
void profileGetS(Addr datablock, Addr PC, const Set &owner, const Set &sharers, NodeID requestor)
void printStats(std::ostream &out) const
uint64_t size() const
Definition: Histogram.hh:57
void add(int64_t value)
Definition: Histogram.cc:93
void printPercent(std::ostream &out) const
Definition: Histogram.cc:199
bool getAllInstructions() const
Definition: Profiler.hh:90
void remove(NodeID index)
Definition: Set.hh:98
void addSet(const Set &obj)
Definition: Set.hh:88
int count() const
Definition: Set.hh:129
STL pair class.
Definition: stl.hh:58
STL vector class.
Definition: stl.hh:37
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 24 > j
Definition: misc_types.hh:57
Bitfield< 5 > r
Definition: pagetable.hh:60
Bitfield< 3 > addr
Definition: types.hh:84
void printSorted(std::ostream &out, int num_of_sequencers, const AddressMap &record_map, std::string description, Profiler *profiler)
AccessTraceForAddress & lookupTraceForAddress(Addr addr, AddressMap &record_map)
AddressProfiler::AddressMap AddressMap
unsigned int NodeID
Definition: TypeDefines.hh:42
Addr makeLineAddress(Addr addr)
Definition: Address.cc:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147

Generated on Wed Dec 21 2022 10:22:38 for gem5 by doxygen 1.9.1