Profiler.cc revision 10919:80069a602c83
1/* 2 * Copyright (c) 1999-2013 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 29/* 30 This file has been modified by Kevin Moore and Dan Nussbaum of the 31 Scalable Systems Research Group at Sun Microsystems Laboratories 32 (http://research.sun.com/scalable/) to support the Adaptive 33 Transactional Memory Test Platform (ATMTP). 34 35 Please send email to atmtp-interest@sun.com with feedback, questions, or 36 to request future announcements about ATMTP. 37 38 ---------------------------------------------------------------------- 39 40 File modification date: 2008-02-23 41 42 ---------------------------------------------------------------------- 43*/ 44 45#include <sys/types.h> 46#include <unistd.h> 47 48#include <algorithm> 49#include <fstream> 50 51#include "base/stl_helpers.hh" 52#include "base/str.hh" 53#include "mem/protocol/MachineType.hh" 54#include "mem/protocol/RubyRequest.hh" 55#include "mem/ruby/network/Network.hh" 56#include "mem/ruby/profiler/AddressProfiler.hh" 57#include "mem/ruby/profiler/Profiler.hh" 58#include "mem/ruby/system/Sequencer.hh" 59 60using namespace std; 61using m5::stl_helpers::operator<<; 62 63Profiler::Profiler(const RubySystemParams *p) 64{ 65 m_hot_lines = p->hot_lines; 66 m_all_instructions = p->all_instructions; 67 68 m_address_profiler_ptr = new AddressProfiler(p->num_of_sequencers, this); 69 m_address_profiler_ptr->setHotLines(m_hot_lines); 70 m_address_profiler_ptr->setAllInstructions(m_all_instructions); 71 72 if (m_all_instructions) { 73 m_inst_profiler_ptr = new AddressProfiler(p->num_of_sequencers, this); 74 m_inst_profiler_ptr->setHotLines(m_hot_lines); 75 m_inst_profiler_ptr->setAllInstructions(m_all_instructions); 76 } 77} 78 79Profiler::~Profiler() 80{ 81} 82 83void 84Profiler::regStats(const std::string &pName) 85{ 86 if (!m_all_instructions) { 87 m_address_profiler_ptr->regStats(pName); 88 } 89 90 if (m_all_instructions) { 91 m_inst_profiler_ptr->regStats(pName); 92 } 93 94 delayHistogram 95 .init(10) 96 .name(pName + ".delayHist") 97 .desc("delay histogram for all message") 98 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 99 100 uint32_t numVNets = Network::getNumberOfVirtualNetworks(); 101 for (int i = 0; i < numVNets; i++) { 102 delayVCHistogram.push_back(new Stats::Histogram()); 103 delayVCHistogram[i] 104 ->init(10) 105 .name(pName + csprintf(".delayVCHist.vnet_%i", i)) 106 .desc(csprintf("delay histogram for vnet_%i", i)) 107 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 108 } 109 110 m_outstandReqHist 111 .init(10) 112 .name(pName + ".outstanding_req_hist") 113 .desc("") 114 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 115 116 m_latencyHist 117 .init(10) 118 .name(pName + ".latency_hist") 119 .desc("") 120 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 121 122 m_hitLatencyHist 123 .init(10) 124 .name(pName + ".hit_latency_hist") 125 .desc("") 126 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 127 128 m_missLatencyHist 129 .init(10) 130 .name(pName + ".miss_latency_hist") 131 .desc("") 132 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 133 134 for (int i = 0; i < RubyRequestType_NUM; i++) { 135 m_typeLatencyHist.push_back(new Stats::Histogram()); 136 m_typeLatencyHist[i] 137 ->init(10) 138 .name(pName + csprintf(".%s.latency_hist", 139 RubyRequestType(i))) 140 .desc("") 141 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 142 143 m_hitTypeLatencyHist.push_back(new Stats::Histogram()); 144 m_hitTypeLatencyHist[i] 145 ->init(10) 146 .name(pName + csprintf(".%s.hit_latency_hist", 147 RubyRequestType(i))) 148 .desc("") 149 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 150 151 m_missTypeLatencyHist.push_back(new Stats::Histogram()); 152 m_missTypeLatencyHist[i] 153 ->init(10) 154 .name(pName + csprintf(".%s.miss_latency_hist", 155 RubyRequestType(i))) 156 .desc("") 157 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 158 } 159 160 for (int i = 0; i < MachineType_NUM; i++) { 161 m_hitMachLatencyHist.push_back(new Stats::Histogram()); 162 m_hitMachLatencyHist[i] 163 ->init(10) 164 .name(pName + csprintf(".%s.hit_mach_latency_hist", 165 MachineType(i))) 166 .desc("") 167 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 168 169 m_missMachLatencyHist.push_back(new Stats::Histogram()); 170 m_missMachLatencyHist[i] 171 ->init(10) 172 .name(pName + csprintf(".%s.miss_mach_latency_hist", 173 MachineType(i))) 174 .desc("") 175 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 176 177 m_IssueToInitialDelayHist.push_back(new Stats::Histogram()); 178 m_IssueToInitialDelayHist[i] 179 ->init(10) 180 .name(pName + csprintf( 181 ".%s.miss_latency_hist.issue_to_initial_request", 182 MachineType(i))) 183 .desc("") 184 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 185 186 m_InitialToForwardDelayHist.push_back(new Stats::Histogram()); 187 m_InitialToForwardDelayHist[i] 188 ->init(10) 189 .name(pName + csprintf(".%s.miss_latency_hist.initial_to_forward", 190 MachineType(i))) 191 .desc("") 192 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 193 194 m_ForwardToFirstResponseDelayHist.push_back(new Stats::Histogram()); 195 m_ForwardToFirstResponseDelayHist[i] 196 ->init(10) 197 .name(pName + csprintf( 198 ".%s.miss_latency_hist.forward_to_first_response", 199 MachineType(i))) 200 .desc("") 201 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 202 203 m_FirstResponseToCompletionDelayHist.push_back(new Stats::Histogram()); 204 m_FirstResponseToCompletionDelayHist[i] 205 ->init(10) 206 .name(pName + csprintf( 207 ".%s.miss_latency_hist.first_response_to_completion", 208 MachineType(i))) 209 .desc("") 210 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 211 212 m_IncompleteTimes[i] 213 .name(pName + csprintf(".%s.incomplete_times", MachineType(i))) 214 .desc("") 215 .flags(Stats::nozero); 216 } 217 218 for (int i = 0; i < RubyRequestType_NUM; i++) { 219 m_hitTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>()); 220 m_missTypeMachLatencyHist.push_back(std::vector<Stats::Histogram *>()); 221 222 for (int j = 0; j < MachineType_NUM; j++) { 223 m_hitTypeMachLatencyHist[i].push_back(new Stats::Histogram()); 224 m_hitTypeMachLatencyHist[i][j] 225 ->init(10) 226 .name(pName + csprintf(".%s.%s.hit_type_mach_latency_hist", 227 RubyRequestType(i), MachineType(j))) 228 .desc("") 229 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 230 231 m_missTypeMachLatencyHist[i].push_back(new Stats::Histogram()); 232 m_missTypeMachLatencyHist[i][j] 233 ->init(10) 234 .name(pName + csprintf(".%s.%s.miss_type_mach_latency_hist", 235 RubyRequestType(i), MachineType(j))) 236 .desc("") 237 .flags(Stats::nozero | Stats::pdf | Stats::oneline); 238 } 239 } 240} 241 242void 243Profiler::collateStats() 244{ 245 if (!m_all_instructions) { 246 m_address_profiler_ptr->collateStats(); 247 } 248 249 if (m_all_instructions) { 250 m_inst_profiler_ptr->collateStats(); 251 } 252 253 uint32_t numVNets = Network::getNumberOfVirtualNetworks(); 254 for (uint32_t i = 0; i < MachineType_NUM; i++) { 255 for (map<uint32_t, AbstractController*>::iterator it = 256 g_abs_controls[i].begin(); 257 it != g_abs_controls[i].end(); ++it) { 258 259 AbstractController *ctr = (*it).second; 260 delayHistogram.add(ctr->getDelayHist()); 261 262 for (uint32_t i = 0; i < numVNets; i++) { 263 delayVCHistogram[i]->add(ctr->getDelayVCHist(i)); 264 } 265 } 266 } 267 268 for (uint32_t i = 0; i < MachineType_NUM; i++) { 269 for (map<uint32_t, AbstractController*>::iterator it = 270 g_abs_controls[i].begin(); 271 it != g_abs_controls[i].end(); ++it) { 272 273 AbstractController *ctr = (*it).second; 274 Sequencer *seq = ctr->getSequencer(); 275 if (seq != NULL) { 276 m_outstandReqHist.add(seq->getOutstandReqHist()); 277 } 278 } 279 } 280 281 for (uint32_t i = 0; i < MachineType_NUM; i++) { 282 for (map<uint32_t, AbstractController*>::iterator it = 283 g_abs_controls[i].begin(); 284 it != g_abs_controls[i].end(); ++it) { 285 286 AbstractController *ctr = (*it).second; 287 Sequencer *seq = ctr->getSequencer(); 288 if (seq != NULL) { 289 // add all the latencies 290 m_latencyHist.add(seq->getLatencyHist()); 291 m_hitLatencyHist.add(seq->getHitLatencyHist()); 292 m_missLatencyHist.add(seq->getMissLatencyHist()); 293 294 // add the per request type latencies 295 for (uint32_t j = 0; j < RubyRequestType_NUM; ++j) { 296 m_typeLatencyHist[j] 297 ->add(seq->getTypeLatencyHist(j)); 298 m_hitTypeLatencyHist[j] 299 ->add(seq->getHitTypeLatencyHist(j)); 300 m_missTypeLatencyHist[j] 301 ->add(seq->getMissTypeLatencyHist(j)); 302 } 303 304 // add the per machine type miss latencies 305 for (uint32_t j = 0; j < MachineType_NUM; ++j) { 306 m_hitMachLatencyHist[j] 307 ->add(seq->getHitMachLatencyHist(j)); 308 m_missMachLatencyHist[j] 309 ->add(seq->getMissMachLatencyHist(j)); 310 311 m_IssueToInitialDelayHist[j]->add( 312 seq->getIssueToInitialDelayHist(MachineType(j))); 313 314 m_InitialToForwardDelayHist[j]->add( 315 seq->getInitialToForwardDelayHist(MachineType(j))); 316 m_ForwardToFirstResponseDelayHist[j]->add(seq-> 317 getForwardRequestToFirstResponseHist(MachineType(j))); 318 319 m_FirstResponseToCompletionDelayHist[j]->add(seq-> 320 getFirstResponseToCompletionDelayHist( 321 MachineType(j))); 322 m_IncompleteTimes[j] += 323 seq->getIncompleteTimes(MachineType(j)); 324 } 325 326 // add the per (request, machine) type miss latencies 327 for (uint32_t j = 0; j < RubyRequestType_NUM; j++) { 328 for (uint32_t k = 0; k < MachineType_NUM; k++) { 329 m_hitTypeMachLatencyHist[j][k]->add( 330 seq->getHitTypeMachLatencyHist(j,k)); 331 m_missTypeMachLatencyHist[j][k]->add( 332 seq->getMissTypeMachLatencyHist(j,k)); 333 } 334 } 335 } 336 } 337 } 338} 339 340void 341Profiler::addAddressTraceSample(const RubyRequest& msg, NodeID id) 342{ 343 if (msg.getType() != RubyRequestType_IFETCH) { 344 // Note: The following line should be commented out if you 345 // want to use the special profiling that is part of the GS320 346 // protocol 347 348 // NOTE: Unless PROFILE_HOT_LINES is enabled, nothing will be 349 // profiled by the AddressProfiler 350 m_address_profiler_ptr-> 351 addTraceSample(msg.getLineAddress(), msg.getProgramCounter(), 352 msg.getType(), msg.getAccessMode(), id, false); 353 } 354} 355