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