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