Profiler.cc revision 6889:323cd43a3c46
15625Sgblack@eecs.umich.edu/* 25625Sgblack@eecs.umich.edu * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood 35625Sgblack@eecs.umich.edu * All rights reserved. 45625Sgblack@eecs.umich.edu * 57087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 67087Snate@binkert.org * modification, are permitted provided that the following conditions are 77087Snate@binkert.org * met: redistributions of source code must retain the above copyright 87087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 97087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 107087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 117087Snate@binkert.org * documentation and/or other materials provided with the distribution; 127087Snate@binkert.org * neither the name of the copyright holders nor the names of its 135625Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 147087Snate@binkert.org * this software without specific prior written permission. 157087Snate@binkert.org * 167087Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177087Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187087Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197087Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207087Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217087Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225625Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237087Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245625Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255625Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265625Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275625Sgblack@eecs.umich.edu */ 285625Sgblack@eecs.umich.edu 295625Sgblack@eecs.umich.edu/* 305625Sgblack@eecs.umich.edu This file has been modified by Kevin Moore and Dan Nussbaum of the 315625Sgblack@eecs.umich.edu Scalable Systems Research Group at Sun Microsystems Laboratories 325625Sgblack@eecs.umich.edu (http://research.sun.com/scalable/) to support the Adaptive 335625Sgblack@eecs.umich.edu Transactional Memory Test Platform (ATMTP). 345625Sgblack@eecs.umich.edu 355625Sgblack@eecs.umich.edu Please send email to atmtp-interest@sun.com with feedback, questions, or 365625Sgblack@eecs.umich.edu to request future announcements about ATMTP. 375625Sgblack@eecs.umich.edu 385625Sgblack@eecs.umich.edu ---------------------------------------------------------------------- 395625Sgblack@eecs.umich.edu 405625Sgblack@eecs.umich.edu File modification date: 2008-02-23 415625Sgblack@eecs.umich.edu 425625Sgblack@eecs.umich.edu ---------------------------------------------------------------------- 436216Snate@binkert.org*/ 448706Sandreas.hansson@arm.com 455625Sgblack@eecs.umich.edu/* 465625Sgblack@eecs.umich.edu * Profiler.cc 475625Sgblack@eecs.umich.edu * 485625Sgblack@eecs.umich.edu * Description: See Profiler.hh 495625Sgblack@eecs.umich.edu * 505625Sgblack@eecs.umich.edu * $Id$ 515625Sgblack@eecs.umich.edu * 525625Sgblack@eecs.umich.edu */ 535625Sgblack@eecs.umich.edu 545625Sgblack@eecs.umich.edu#include "mem/ruby/profiler/Profiler.hh" 555625Sgblack@eecs.umich.edu#include "mem/ruby/profiler/AddressProfiler.hh" 565625Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh" 575625Sgblack@eecs.umich.edu#include "mem/ruby/network/Network.hh" 585625Sgblack@eecs.umich.edu#include "mem/gems_common/PrioHeap.hh" 595625Sgblack@eecs.umich.edu#include "mem/protocol/CacheMsg.hh" 605625Sgblack@eecs.umich.edu#include "mem/protocol/Protocol.hh" 615625Sgblack@eecs.umich.edu#include "mem/gems_common/util.hh" 625625Sgblack@eecs.umich.edu#include "mem/gems_common/Map.hh" 635625Sgblack@eecs.umich.edu#include "mem/ruby/common/Debug.hh" 645625Sgblack@eecs.umich.edu#include "mem/protocol/MachineType.hh" 655625Sgblack@eecs.umich.edu 665625Sgblack@eecs.umich.edu#include "mem/ruby/system/System.hh" 675625Sgblack@eecs.umich.edu 685625Sgblack@eecs.umich.edu// Allows use of times() library call, which determines virtual runtime 695625Sgblack@eecs.umich.edu#include <sys/times.h> 705625Sgblack@eecs.umich.edu 715625Sgblack@eecs.umich.eduextern std::ostream * debug_cout_ptr; 725625Sgblack@eecs.umich.edu 738706Sandreas.hansson@arm.comstatic double process_memory_total(); 745625Sgblack@eecs.umich.edustatic double process_memory_resident(); 758737Skoansin.tan@gmail.com 768706Sandreas.hansson@arm.comProfiler::Profiler(const Params *p) 775625Sgblack@eecs.umich.edu : SimObject(p) 785625Sgblack@eecs.umich.edu{ 795625Sgblack@eecs.umich.edu m_requestProfileMap_ptr = new Map<string, int>; 805625Sgblack@eecs.umich.edu 815625Sgblack@eecs.umich.edu m_inst_profiler_ptr = NULL; 825625Sgblack@eecs.umich.edu m_address_profiler_ptr = NULL; 835625Sgblack@eecs.umich.edu 845625Sgblack@eecs.umich.edu m_real_time_start_time = time(NULL); // Not reset in clearStats() 855625Sgblack@eecs.umich.edu m_stats_period = 1000000; // Default 865625Sgblack@eecs.umich.edu m_periodic_output_file_ptr = &cerr; 878706Sandreas.hansson@arm.com 885625Sgblack@eecs.umich.edu m_hot_lines = p->hot_lines; 895625Sgblack@eecs.umich.edu m_all_instructions = p->all_instructions; 905625Sgblack@eecs.umich.edu 915625Sgblack@eecs.umich.edu // 925625Sgblack@eecs.umich.edu // Initialize the memory controller profiler structs 935625Sgblack@eecs.umich.edu // 945625Sgblack@eecs.umich.edu m_mc_profilers.setSize(p->mem_cntrl_count); 955625Sgblack@eecs.umich.edu for (int mem_cntrl = 0; mem_cntrl < p->mem_cntrl_count; mem_cntrl++) { 965625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl] = new memory_control_profiler; 975625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memReq = 0; 985625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memBankBusy = 0; 995625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memBusBusy = 0; 1008706Sandreas.hansson@arm.com m_mc_profilers[mem_cntrl]->m_memReadWriteBusy = 0; 1015625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memDataBusBusy = 0; 1025625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memTfawBusy = 0; 1035625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memRefresh = 0; 1045625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memRead = 0; 1055625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memWrite = 0; 1065625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memWaitCycles = 0; 1075625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memInputQ = 0; 1085625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memBankQ = 0; 1095625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memArbWait = 0; 1108706Sandreas.hansson@arm.com m_mc_profilers[mem_cntrl]->m_memRandBusy = 0; 1115625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memNotOld = 0; 1125625Sgblack@eecs.umich.edu 1135625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_banks_per_rank = p->banks_per_rank; 1145625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_ranks_per_dimm = p->ranks_per_dimm; 1155625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_dimms_per_channel = 1165625Sgblack@eecs.umich.edu p->dimms_per_channel; 1175625Sgblack@eecs.umich.edu 1185625Sgblack@eecs.umich.edu int totalBanks = p->banks_per_rank * 1195625Sgblack@eecs.umich.edu p->ranks_per_dimm * 1205625Sgblack@eecs.umich.edu p->dimms_per_channel; 1215625Sgblack@eecs.umich.edu 1225625Sgblack@eecs.umich.edu m_mc_profilers[mem_cntrl]->m_memBankCount.setSize(totalBanks); 1238706Sandreas.hansson@arm.com } 1245625Sgblack@eecs.umich.edu 1255625Sgblack@eecs.umich.edu m_hot_lines = false; 1265625Sgblack@eecs.umich.edu m_all_instructions = false; 1278706Sandreas.hansson@arm.com 1285625Sgblack@eecs.umich.edu m_address_profiler_ptr = new AddressProfiler; 1295625Sgblack@eecs.umich.edu m_address_profiler_ptr -> setHotLines(m_hot_lines); 1305625Sgblack@eecs.umich.edu m_address_profiler_ptr -> setAllInstructions(m_all_instructions); 1318706Sandreas.hansson@arm.com 1325625Sgblack@eecs.umich.edu if (m_all_instructions) { 1335625Sgblack@eecs.umich.edu m_inst_profiler_ptr = new AddressProfiler; 1348706Sandreas.hansson@arm.com m_inst_profiler_ptr -> setHotLines(m_hot_lines); 1355625Sgblack@eecs.umich.edu m_inst_profiler_ptr -> setAllInstructions(m_all_instructions); 1365625Sgblack@eecs.umich.edu } 1378706Sandreas.hansson@arm.com} 1385625Sgblack@eecs.umich.edu 1395625Sgblack@eecs.umich.eduProfiler::~Profiler() 1405625Sgblack@eecs.umich.edu{ 1418706Sandreas.hansson@arm.com if (m_periodic_output_file_ptr != &cerr) { 1425625Sgblack@eecs.umich.edu delete m_periodic_output_file_ptr; 1435625Sgblack@eecs.umich.edu } 1448706Sandreas.hansson@arm.com 1455625Sgblack@eecs.umich.edu for (int mem_cntrl = 0; 1465625Sgblack@eecs.umich.edu mem_cntrl < m_mc_profilers.size(); 1475625Sgblack@eecs.umich.edu mem_cntrl++) { 1485625Sgblack@eecs.umich.edu delete m_mc_profilers[mem_cntrl]; 1495625Sgblack@eecs.umich.edu } 1505625Sgblack@eecs.umich.edu 1515625Sgblack@eecs.umich.edu delete m_requestProfileMap_ptr; 1525625Sgblack@eecs.umich.edu} 1535625Sgblack@eecs.umich.edu 1545625Sgblack@eecs.umich.eduvoid Profiler::wakeup() 1555625Sgblack@eecs.umich.edu{ 1565625Sgblack@eecs.umich.edu // FIXME - avoid the repeated code 1575625Sgblack@eecs.umich.edu 1585625Sgblack@eecs.umich.edu Vector<integer_t> perProcCycleCount; 1595625Sgblack@eecs.umich.edu perProcCycleCount.setSize(RubySystem::getNumberOfSequencers()); 1605625Sgblack@eecs.umich.edu 1618706Sandreas.hansson@arm.com for(int i=0; i < RubySystem::getNumberOfSequencers(); i++) { 1625625Sgblack@eecs.umich.edu perProcCycleCount[i] = g_system_ptr->getCycleCount(i) - m_cycles_executed_at_start[i] + 1; 1635625Sgblack@eecs.umich.edu // The +1 allows us to avoid division by zero 1648706Sandreas.hansson@arm.com } 1655625Sgblack@eecs.umich.edu 1665625Sgblack@eecs.umich.edu integer_t total_misses = m_perProcTotalMisses.sum(); 1675625Sgblack@eecs.umich.edu integer_t simics_cycles_executed = perProcCycleCount.sum(); 1685625Sgblack@eecs.umich.edu integer_t transactions_started = m_perProcStartTransaction.sum(); 1695625Sgblack@eecs.umich.edu integer_t transactions_ended = m_perProcEndTransaction.sum(); 1705625Sgblack@eecs.umich.edu 1715625Sgblack@eecs.umich.edu (*m_periodic_output_file_ptr) << "ruby_cycles: " 1725625Sgblack@eecs.umich.edu << g_eventQueue_ptr->getTime()-m_ruby_start 1735625Sgblack@eecs.umich.edu << endl; 1748706Sandreas.hansson@arm.com 1755625Sgblack@eecs.umich.edu (*m_periodic_output_file_ptr) << "total_misses: " 1765625Sgblack@eecs.umich.edu << total_misses 1778706Sandreas.hansson@arm.com << " " 1785625Sgblack@eecs.umich.edu << m_perProcTotalMisses 1798706Sandreas.hansson@arm.com << endl; 1805625Sgblack@eecs.umich.edu 1815625Sgblack@eecs.umich.edu (*m_periodic_output_file_ptr) << "simics_cycles_executed: " 1825625Sgblack@eecs.umich.edu << simics_cycles_executed 1835625Sgblack@eecs.umich.edu << " " 1845625Sgblack@eecs.umich.edu << perProcCycleCount 1855625Sgblack@eecs.umich.edu << endl; 1865625Sgblack@eecs.umich.edu 1875625Sgblack@eecs.umich.edu (*m_periodic_output_file_ptr) << "transactions_started: " 1885625Sgblack@eecs.umich.edu << transactions_started 1895625Sgblack@eecs.umich.edu << " " 1905625Sgblack@eecs.umich.edu << m_perProcStartTransaction 1915625Sgblack@eecs.umich.edu << endl; 1928706Sandreas.hansson@arm.com 1935625Sgblack@eecs.umich.edu (*m_periodic_output_file_ptr) << "transactions_ended: " 1945625Sgblack@eecs.umich.edu << transactions_ended 1955625Sgblack@eecs.umich.edu << " " 1968706Sandreas.hansson@arm.com << m_perProcEndTransaction 1975625Sgblack@eecs.umich.edu << endl; 1985625Sgblack@eecs.umich.edu 1995625Sgblack@eecs.umich.edu (*m_periodic_output_file_ptr) << "mbytes_resident: " 2005625Sgblack@eecs.umich.edu << process_memory_resident() 2015625Sgblack@eecs.umich.edu << endl; 2028706Sandreas.hansson@arm.com 2035625Sgblack@eecs.umich.edu (*m_periodic_output_file_ptr) << "mbytes_total: " 2045625Sgblack@eecs.umich.edu << process_memory_total() 2055625Sgblack@eecs.umich.edu << endl; 2065625Sgblack@eecs.umich.edu 2078706Sandreas.hansson@arm.com if (process_memory_total() > 0) { 2088706Sandreas.hansson@arm.com (*m_periodic_output_file_ptr) << "resident_ratio: " 2095625Sgblack@eecs.umich.edu << process_memory_resident()/process_memory_total() 2108706Sandreas.hansson@arm.com << endl; 2118706Sandreas.hansson@arm.com } 2128706Sandreas.hansson@arm.com 2138706Sandreas.hansson@arm.com (*m_periodic_output_file_ptr) << "miss_latency: " 2145625Sgblack@eecs.umich.edu << m_allMissLatencyHistogram 2155625Sgblack@eecs.umich.edu << endl; 2168706Sandreas.hansson@arm.com 2175625Sgblack@eecs.umich.edu *m_periodic_output_file_ptr << endl; 2185625Sgblack@eecs.umich.edu 2195625Sgblack@eecs.umich.edu if (m_all_instructions) { 2205625Sgblack@eecs.umich.edu m_inst_profiler_ptr->printStats(*m_periodic_output_file_ptr); 2215625Sgblack@eecs.umich.edu } 2225625Sgblack@eecs.umich.edu 2238706Sandreas.hansson@arm.com //g_system_ptr->getNetwork()->printStats(*m_periodic_output_file_ptr); 2245625Sgblack@eecs.umich.edu g_eventQueue_ptr->scheduleEvent(this, m_stats_period); 2255625Sgblack@eecs.umich.edu} 2265625Sgblack@eecs.umich.edu 2278706Sandreas.hansson@arm.comvoid Profiler::setPeriodicStatsFile(const string& filename) 2285625Sgblack@eecs.umich.edu{ 2295625Sgblack@eecs.umich.edu cout << "Recording periodic statistics to file '" << filename << "' every " 2305625Sgblack@eecs.umich.edu << m_stats_period << " Ruby cycles" << endl; 2315625Sgblack@eecs.umich.edu 2325625Sgblack@eecs.umich.edu if (m_periodic_output_file_ptr != &cerr) { 2335625Sgblack@eecs.umich.edu delete m_periodic_output_file_ptr; 2348706Sandreas.hansson@arm.com } 2355625Sgblack@eecs.umich.edu 2365625Sgblack@eecs.umich.edu m_periodic_output_file_ptr = new ofstream(filename.c_str()); 2375625Sgblack@eecs.umich.edu g_eventQueue_ptr->scheduleEvent(this, 1); 2388706Sandreas.hansson@arm.com} 2395625Sgblack@eecs.umich.edu 2408706Sandreas.hansson@arm.comvoid Profiler::setPeriodicStatsInterval(integer_t period) 2415625Sgblack@eecs.umich.edu{ 2425625Sgblack@eecs.umich.edu cout << "Recording periodic statistics every " << m_stats_period 2435625Sgblack@eecs.umich.edu << " Ruby cycles" << endl; 2448706Sandreas.hansson@arm.com 2455625Sgblack@eecs.umich.edu m_stats_period = period; 2465625Sgblack@eecs.umich.edu g_eventQueue_ptr->scheduleEvent(this, 1); 2475625Sgblack@eecs.umich.edu} 2485625Sgblack@eecs.umich.edu 2495625Sgblack@eecs.umich.eduvoid Profiler::printConfig(ostream& out) const 2505625Sgblack@eecs.umich.edu{ 2515625Sgblack@eecs.umich.edu out << endl; 2525625Sgblack@eecs.umich.edu out << "Profiler Configuration" << endl; 2535625Sgblack@eecs.umich.edu out << "----------------------" << endl; 2545625Sgblack@eecs.umich.edu out << "periodic_stats_period: " << m_stats_period << endl; 2555625Sgblack@eecs.umich.edu} 2565625Sgblack@eecs.umich.edu 2575625Sgblack@eecs.umich.eduvoid Profiler::print(ostream& out) const 2585625Sgblack@eecs.umich.edu{ 2595625Sgblack@eecs.umich.edu out << "[Profiler]"; 2605625Sgblack@eecs.umich.edu} 2615625Sgblack@eecs.umich.edu 2625625Sgblack@eecs.umich.eduvoid Profiler::printStats(ostream& out, bool short_stats) 2635625Sgblack@eecs.umich.edu{ 2648706Sandreas.hansson@arm.com out << endl; 2655625Sgblack@eecs.umich.edu if (short_stats) { 2668706Sandreas.hansson@arm.com out << "SHORT "; 2678706Sandreas.hansson@arm.com } 2688706Sandreas.hansson@arm.com out << "Profiler Stats" << endl; 2698706Sandreas.hansson@arm.com out << "--------------" << endl; 2708706Sandreas.hansson@arm.com 2718706Sandreas.hansson@arm.com time_t real_time_current = time(NULL); 2725625Sgblack@eecs.umich.edu double seconds = difftime(real_time_current, m_real_time_start_time); 2735625Sgblack@eecs.umich.edu double minutes = seconds/60.0; 2748706Sandreas.hansson@arm.com double hours = minutes/60.0; 2758706Sandreas.hansson@arm.com double days = hours/24.0; 2765625Sgblack@eecs.umich.edu Time ruby_cycles = g_eventQueue_ptr->getTime()-m_ruby_start; 2775625Sgblack@eecs.umich.edu 2785625Sgblack@eecs.umich.edu if (!short_stats) { 2795625Sgblack@eecs.umich.edu out << "Elapsed_time_in_seconds: " << seconds << endl; 2805625Sgblack@eecs.umich.edu out << "Elapsed_time_in_minutes: " << minutes << endl; 2815625Sgblack@eecs.umich.edu out << "Elapsed_time_in_hours: " << hours << endl; 2825625Sgblack@eecs.umich.edu out << "Elapsed_time_in_days: " << days << endl; 2835625Sgblack@eecs.umich.edu out << endl; 2845625Sgblack@eecs.umich.edu } 2855625Sgblack@eecs.umich.edu 2865625Sgblack@eecs.umich.edu // print the virtual runtimes as well 2875625Sgblack@eecs.umich.edu struct tms vtime; 2885625Sgblack@eecs.umich.edu times(&vtime); 2895625Sgblack@eecs.umich.edu seconds = (vtime.tms_utime + vtime.tms_stime) / 100.0; 2905625Sgblack@eecs.umich.edu minutes = seconds / 60.0; 2915625Sgblack@eecs.umich.edu hours = minutes / 60.0; 2925625Sgblack@eecs.umich.edu days = hours / 24.0; 2935625Sgblack@eecs.umich.edu out << "Virtual_time_in_seconds: " << seconds << endl; 2945625Sgblack@eecs.umich.edu out << "Virtual_time_in_minutes: " << minutes << endl; 2955625Sgblack@eecs.umich.edu out << "Virtual_time_in_hours: " << hours << endl; 2965625Sgblack@eecs.umich.edu out << "Virtual_time_in_days: " << days << endl; 2975625Sgblack@eecs.umich.edu out << endl; 2985625Sgblack@eecs.umich.edu 2995625Sgblack@eecs.umich.edu out << "Ruby_current_time: " << g_eventQueue_ptr->getTime() << endl; 3005625Sgblack@eecs.umich.edu out << "Ruby_start_time: " << m_ruby_start << endl; 3018706Sandreas.hansson@arm.com out << "Ruby_cycles: " << ruby_cycles << endl; 3025625Sgblack@eecs.umich.edu out << endl; 3038706Sandreas.hansson@arm.com 3048706Sandreas.hansson@arm.com if (!short_stats) { 3058706Sandreas.hansson@arm.com out << "mbytes_resident: " << process_memory_resident() << endl; 3065625Sgblack@eecs.umich.edu out << "mbytes_total: " << process_memory_total() << endl; 3075625Sgblack@eecs.umich.edu if (process_memory_total() > 0) { 3085625Sgblack@eecs.umich.edu out << "resident_ratio: " 3095625Sgblack@eecs.umich.edu << process_memory_resident()/process_memory_total() << endl; 3105625Sgblack@eecs.umich.edu } 3115625Sgblack@eecs.umich.edu out << endl; 3125625Sgblack@eecs.umich.edu 3135625Sgblack@eecs.umich.edu } 3145625Sgblack@eecs.umich.edu 3155625Sgblack@eecs.umich.edu Vector<integer_t> perProcCycleCount; 3165625Sgblack@eecs.umich.edu Vector<double> perProcCyclesPerTrans; 3175625Sgblack@eecs.umich.edu Vector<double> perProcMissesPerTrans; 3185625Sgblack@eecs.umich.edu 3195625Sgblack@eecs.umich.edu 3205625Sgblack@eecs.umich.edu perProcCycleCount.setSize(RubySystem::getNumberOfSequencers()); 3218706Sandreas.hansson@arm.com perProcCyclesPerTrans.setSize(RubySystem::getNumberOfSequencers()); 3225625Sgblack@eecs.umich.edu perProcMissesPerTrans.setSize(RubySystem::getNumberOfSequencers()); 3238706Sandreas.hansson@arm.com 3248706Sandreas.hansson@arm.com for(int i=0; i < RubySystem::getNumberOfSequencers(); i++) { 3258706Sandreas.hansson@arm.com perProcCycleCount[i] = g_system_ptr->getCycleCount(i) - m_cycles_executed_at_start[i] + 1; 3268706Sandreas.hansson@arm.com // The +1 allows us to avoid division by zero 3278706Sandreas.hansson@arm.com 3285625Sgblack@eecs.umich.edu int trans = m_perProcEndTransaction[i]; 3295625Sgblack@eecs.umich.edu if (trans == 0) { 3305625Sgblack@eecs.umich.edu perProcCyclesPerTrans[i] = 0; 3315625Sgblack@eecs.umich.edu perProcMissesPerTrans[i] = 0; 3325625Sgblack@eecs.umich.edu } else { 3335625Sgblack@eecs.umich.edu perProcCyclesPerTrans[i] = ruby_cycles / double(trans); 3345625Sgblack@eecs.umich.edu perProcMissesPerTrans[i] = m_perProcTotalMisses[i] / double(trans); 3355625Sgblack@eecs.umich.edu } 3365625Sgblack@eecs.umich.edu } 3375625Sgblack@eecs.umich.edu 3385625Sgblack@eecs.umich.edu integer_t total_misses = m_perProcTotalMisses.sum(); 3395625Sgblack@eecs.umich.edu integer_t user_misses = m_perProcUserMisses.sum(); 3405625Sgblack@eecs.umich.edu integer_t supervisor_misses = m_perProcSupervisorMisses.sum(); 3415625Sgblack@eecs.umich.edu integer_t simics_cycles_executed = perProcCycleCount.sum(); 3425625Sgblack@eecs.umich.edu integer_t transactions_started = m_perProcStartTransaction.sum(); 3435625Sgblack@eecs.umich.edu integer_t transactions_ended = m_perProcEndTransaction.sum(); 3445625Sgblack@eecs.umich.edu 3455625Sgblack@eecs.umich.edu double cycles_per_transaction = (transactions_ended != 0) ? (RubySystem::getNumberOfSequencers() * double(ruby_cycles)) / double(transactions_ended) : 0; 3468706Sandreas.hansson@arm.com double misses_per_transaction = (transactions_ended != 0) ? double(total_misses) / double(transactions_ended) : 0; 3475625Sgblack@eecs.umich.edu 3488706Sandreas.hansson@arm.com out << "Total_misses: " << total_misses << endl; 3498706Sandreas.hansson@arm.com out << "total_misses: " << total_misses << " " << m_perProcTotalMisses << endl; 3508706Sandreas.hansson@arm.com out << "user_misses: " << user_misses << " " << m_perProcUserMisses << endl; 3518706Sandreas.hansson@arm.com out << "supervisor_misses: " << supervisor_misses << " " << m_perProcSupervisorMisses << endl; 3528706Sandreas.hansson@arm.com out << endl; 3538706Sandreas.hansson@arm.com out << "ruby_cycles_executed: " << simics_cycles_executed << " " << perProcCycleCount << endl; 3548706Sandreas.hansson@arm.com out << endl; 3555625Sgblack@eecs.umich.edu out << "transactions_started: " << transactions_started << " " << m_perProcStartTransaction << endl; 3565625Sgblack@eecs.umich.edu out << "transactions_ended: " << transactions_ended << " " << m_perProcEndTransaction << endl; 3575625Sgblack@eecs.umich.edu out << "cycles_per_transaction: " << cycles_per_transaction << " " << perProcCyclesPerTrans << endl; 3585625Sgblack@eecs.umich.edu out << "misses_per_transaction: " << misses_per_transaction << " " << perProcMissesPerTrans << endl; 3595625Sgblack@eecs.umich.edu 3605625Sgblack@eecs.umich.edu out << endl; 3615625Sgblack@eecs.umich.edu 3625625Sgblack@eecs.umich.edu out << endl; 3635625Sgblack@eecs.umich.edu 3645625Sgblack@eecs.umich.edu for (int mem_cntrl = 0; 3655625Sgblack@eecs.umich.edu mem_cntrl < m_mc_profilers.size(); 3665625Sgblack@eecs.umich.edu mem_cntrl++) { 3675625Sgblack@eecs.umich.edu uint64 m_memReq = m_mc_profilers[mem_cntrl]->m_memReq; 3685625Sgblack@eecs.umich.edu uint64 m_memRefresh = m_mc_profilers[mem_cntrl]->m_memRefresh; 3695625Sgblack@eecs.umich.edu uint64 m_memInputQ = m_mc_profilers[mem_cntrl]->m_memInputQ; 3705625Sgblack@eecs.umich.edu uint64 m_memBankQ = m_mc_profilers[mem_cntrl]->m_memBankQ; 3715625Sgblack@eecs.umich.edu uint64 m_memWaitCycles = m_mc_profilers[mem_cntrl]->m_memWaitCycles; 3725625Sgblack@eecs.umich.edu uint64 m_memRead = m_mc_profilers[mem_cntrl]->m_memRead; 3735625Sgblack@eecs.umich.edu uint64 m_memWrite = m_mc_profilers[mem_cntrl]->m_memWrite; 3745625Sgblack@eecs.umich.edu uint64 m_memBankBusy = m_mc_profilers[mem_cntrl]->m_memBankBusy; 3755625Sgblack@eecs.umich.edu uint64 m_memRandBusy = m_mc_profilers[mem_cntrl]->m_memRandBusy; 3765625Sgblack@eecs.umich.edu uint64 m_memNotOld = m_mc_profilers[mem_cntrl]->m_memNotOld; 3775625Sgblack@eecs.umich.edu uint64 m_memArbWait = m_mc_profilers[mem_cntrl]->m_memArbWait; 3785625Sgblack@eecs.umich.edu uint64 m_memBusBusy = m_mc_profilers[mem_cntrl]->m_memBusBusy; 3795625Sgblack@eecs.umich.edu uint64 m_memTfawBusy = m_mc_profilers[mem_cntrl]->m_memTfawBusy; 3805625Sgblack@eecs.umich.edu uint64 m_memReadWriteBusy = m_mc_profilers[mem_cntrl]->m_memReadWriteBusy; 3815625Sgblack@eecs.umich.edu uint64 m_memDataBusBusy = m_mc_profilers[mem_cntrl]->m_memDataBusBusy; 3825625Sgblack@eecs.umich.edu Vector<uint64> m_memBankCount = m_mc_profilers[mem_cntrl]->m_memBankCount; 3835625Sgblack@eecs.umich.edu 3848706Sandreas.hansson@arm.com if (m_memReq || m_memRefresh) { // if there's a memory controller at all 3855625Sgblack@eecs.umich.edu uint64 total_stalls = m_memInputQ + m_memBankQ + m_memWaitCycles; 3868706Sandreas.hansson@arm.com double stallsPerReq = total_stalls * 1.0 / m_memReq; 3878706Sandreas.hansson@arm.com out << "Memory control " << mem_cntrl << ":" << endl; 3888706Sandreas.hansson@arm.com out << " memory_total_requests: " << m_memReq << endl; // does not include refreshes 3898706Sandreas.hansson@arm.com out << " memory_reads: " << m_memRead << endl; 3908706Sandreas.hansson@arm.com out << " memory_writes: " << m_memWrite << endl; 3915625Sgblack@eecs.umich.edu out << " memory_refreshes: " << m_memRefresh << endl; 3925625Sgblack@eecs.umich.edu out << " memory_total_request_delays: " << total_stalls << endl; 3935625Sgblack@eecs.umich.edu out << " memory_delays_per_request: " << stallsPerReq << endl; 3945625Sgblack@eecs.umich.edu out << " memory_delays_in_input_queue: " << m_memInputQ << endl; 3955625Sgblack@eecs.umich.edu out << " memory_delays_behind_head_of_bank_queue: " << m_memBankQ << endl; 3965625Sgblack@eecs.umich.edu out << " memory_delays_stalled_at_head_of_bank_queue: " << m_memWaitCycles << endl; 3975625Sgblack@eecs.umich.edu // Note: The following "memory stalls" entries are a breakdown of the 3985625Sgblack@eecs.umich.edu // cycles which already showed up in m_memWaitCycles. The order is 3995625Sgblack@eecs.umich.edu // significant; it is the priority of attributing the cycles. 4005625Sgblack@eecs.umich.edu // For example, bank_busy is before arbitration because if the bank was 4015625Sgblack@eecs.umich.edu // busy, we didn't even check arbitration. 4025625Sgblack@eecs.umich.edu // Note: "not old enough" means that since we grouped waiting heads-of-queues 4035625Sgblack@eecs.umich.edu // into batches to avoid starvation, a request in a newer batch 4045625Sgblack@eecs.umich.edu // didn't try to arbitrate yet because there are older requests waiting. 4055625Sgblack@eecs.umich.edu out << " memory_stalls_for_bank_busy: " << m_memBankBusy << endl; 4065625Sgblack@eecs.umich.edu out << " memory_stalls_for_random_busy: " << m_memRandBusy << endl; 4075625Sgblack@eecs.umich.edu out << " memory_stalls_for_anti_starvation: " << m_memNotOld << endl; 4088706Sandreas.hansson@arm.com out << " memory_stalls_for_arbitration: " << m_memArbWait << endl; 4095625Sgblack@eecs.umich.edu out << " memory_stalls_for_bus: " << m_memBusBusy << endl; 4108706Sandreas.hansson@arm.com out << " memory_stalls_for_tfaw: " << m_memTfawBusy << endl; 4118706Sandreas.hansson@arm.com out << " memory_stalls_for_read_write_turnaround: " << m_memReadWriteBusy << endl; 4128706Sandreas.hansson@arm.com out << " memory_stalls_for_read_read_turnaround: " << m_memDataBusBusy << endl; 4138706Sandreas.hansson@arm.com out << " accesses_per_bank: "; 4145625Sgblack@eecs.umich.edu for (int bank=0; bank < m_memBankCount.size(); bank++) { 4155625Sgblack@eecs.umich.edu out << m_memBankCount[bank] << " "; 4168706Sandreas.hansson@arm.com //if ((bank % 8) == 7) out << " " << endl; 4175625Sgblack@eecs.umich.edu } 4185625Sgblack@eecs.umich.edu out << endl; 4195625Sgblack@eecs.umich.edu out << endl; 4205625Sgblack@eecs.umich.edu } 4215625Sgblack@eecs.umich.edu } 4225625Sgblack@eecs.umich.edu if (!short_stats) { 4235625Sgblack@eecs.umich.edu out << "Busy Controller Counts:" << endl; 4245625Sgblack@eecs.umich.edu for(int i=0; i < MachineType_NUM; i++) { 4255625Sgblack@eecs.umich.edu for(int j=0; j < MachineType_base_count((MachineType)i); j++) { 4265625Sgblack@eecs.umich.edu MachineID machID; 4275625Sgblack@eecs.umich.edu machID.type = (MachineType)i; 4285625Sgblack@eecs.umich.edu machID.num = j; 4295625Sgblack@eecs.umich.edu out << machID << ":" << m_busyControllerCount[i][j] << " "; 4305625Sgblack@eecs.umich.edu if ((j+1)%8 == 0) { 4315625Sgblack@eecs.umich.edu out << endl; 4325625Sgblack@eecs.umich.edu } 4335625Sgblack@eecs.umich.edu } 4345625Sgblack@eecs.umich.edu out << endl; 4355625Sgblack@eecs.umich.edu } 4365625Sgblack@eecs.umich.edu out << endl; 4378706Sandreas.hansson@arm.com 4385625Sgblack@eecs.umich.edu out << "Busy Bank Count:" << m_busyBankCount << endl; 4398706Sandreas.hansson@arm.com out << endl; 4408706Sandreas.hansson@arm.com 4418706Sandreas.hansson@arm.com out << "sequencer_requests_outstanding: " << m_sequencer_requests << endl; 4428706Sandreas.hansson@arm.com out << endl; 4435625Sgblack@eecs.umich.edu } 4445625Sgblack@eecs.umich.edu 4455625Sgblack@eecs.umich.edu if (!short_stats) { 4465625Sgblack@eecs.umich.edu out << "All Non-Zero Cycle Demand Cache Accesses" << endl; 4475625Sgblack@eecs.umich.edu out << "----------------------------------------" << endl; 4485625Sgblack@eecs.umich.edu out << "miss_latency: " << m_allMissLatencyHistogram << endl; 4495625Sgblack@eecs.umich.edu for(int i=0; i<m_missLatencyHistograms.size(); i++) { 4505625Sgblack@eecs.umich.edu if (m_missLatencyHistograms[i].size() > 0) { 4515625Sgblack@eecs.umich.edu out << "miss_latency_" << RubyRequestType(i) << ": " << m_missLatencyHistograms[i] << endl; 4525625Sgblack@eecs.umich.edu } 4535625Sgblack@eecs.umich.edu } 4545625Sgblack@eecs.umich.edu for(int i=0; i<m_machLatencyHistograms.size(); i++) { 4555625Sgblack@eecs.umich.edu if (m_machLatencyHistograms[i].size() > 0) { 4565625Sgblack@eecs.umich.edu out << "miss_latency_" << GenericMachineType(i) << ": " << m_machLatencyHistograms[i] << endl; 4575625Sgblack@eecs.umich.edu } 4585625Sgblack@eecs.umich.edu } 459 460 out << endl; 461 462 out << "All Non-Zero Cycle SW Prefetch Requests" << endl; 463 out << "------------------------------------" << endl; 464 out << "prefetch_latency: " << m_allSWPrefetchLatencyHistogram << endl; 465 for(int i=0; i<m_SWPrefetchLatencyHistograms.size(); i++) { 466 if (m_SWPrefetchLatencyHistograms[i].size() > 0) { 467 out << "prefetch_latency_" << CacheRequestType(i) << ": " << m_SWPrefetchLatencyHistograms[i] << endl; 468 } 469 } 470 for(int i=0; i<m_SWPrefetchMachLatencyHistograms.size(); i++) { 471 if (m_SWPrefetchMachLatencyHistograms[i].size() > 0) { 472 out << "prefetch_latency_" << GenericMachineType(i) << ": " << m_SWPrefetchMachLatencyHistograms[i] << endl; 473 } 474 } 475 out << "prefetch_latency_L2Miss:" << m_SWPrefetchL2MissLatencyHistogram << endl; 476 477 if (m_all_sharing_histogram.size() > 0) { 478 out << "all_sharing: " << m_all_sharing_histogram << endl; 479 out << "read_sharing: " << m_read_sharing_histogram << endl; 480 out << "write_sharing: " << m_write_sharing_histogram << endl; 481 482 out << "all_sharing_percent: "; m_all_sharing_histogram.printPercent(out); out << endl; 483 out << "read_sharing_percent: "; m_read_sharing_histogram.printPercent(out); out << endl; 484 out << "write_sharing_percent: "; m_write_sharing_histogram.printPercent(out); out << endl; 485 486 int64 total_miss = m_cache_to_cache + m_memory_to_cache; 487 out << "all_misses: " << total_miss << endl; 488 out << "cache_to_cache_misses: " << m_cache_to_cache << endl; 489 out << "memory_to_cache_misses: " << m_memory_to_cache << endl; 490 out << "cache_to_cache_percent: " << 100.0 * (double(m_cache_to_cache) / double(total_miss)) << endl; 491 out << "memory_to_cache_percent: " << 100.0 * (double(m_memory_to_cache) / double(total_miss)) << endl; 492 out << endl; 493 } 494 495 if (m_outstanding_requests.size() > 0) { 496 out << "outstanding_requests: "; m_outstanding_requests.printPercent(out); out << endl; 497 out << endl; 498 } 499 } 500 501 if (!short_stats) { 502 out << "Request vs. RubySystem State Profile" << endl; 503 out << "--------------------------------" << endl; 504 out << endl; 505 506 Vector<string> requestProfileKeys = m_requestProfileMap_ptr->keys(); 507 requestProfileKeys.sortVector(); 508 509 for(int i=0; i<requestProfileKeys.size(); i++) { 510 int temp_int = m_requestProfileMap_ptr->lookup(requestProfileKeys[i]); 511 double percent = (100.0*double(temp_int))/double(m_requests); 512 while (requestProfileKeys[i] != "") { 513 out << setw(10) << string_split(requestProfileKeys[i], ':'); 514 } 515 out << setw(11) << temp_int; 516 out << setw(14) << percent << endl; 517 } 518 out << endl; 519 520 out << "filter_action: " << m_filter_action_histogram << endl; 521 522 if (!m_all_instructions) { 523 m_address_profiler_ptr->printStats(out); 524 } 525 526 if (m_all_instructions) { 527 m_inst_profiler_ptr->printStats(out); 528 } 529 530 out << endl; 531 out << "Message Delayed Cycles" << endl; 532 out << "----------------------" << endl; 533 out << "Total_delay_cycles: " << m_delayedCyclesHistogram << endl; 534 out << "Total_nonPF_delay_cycles: " << m_delayedCyclesNonPFHistogram << endl; 535 for (int i = 0; i < m_delayedCyclesVCHistograms.size(); i++) { 536 out << " virtual_network_" << i << "_delay_cycles: " << m_delayedCyclesVCHistograms[i] << endl; 537 } 538 539 printResourceUsage(out); 540 } 541 542} 543 544void Profiler::printResourceUsage(ostream& out) const 545{ 546 out << endl; 547 out << "Resource Usage" << endl; 548 out << "--------------" << endl; 549 550 integer_t pagesize = getpagesize(); // page size in bytes 551 out << "page_size: " << pagesize << endl; 552 553 rusage usage; 554 getrusage (RUSAGE_SELF, &usage); 555 556 out << "user_time: " << usage.ru_utime.tv_sec << endl; 557 out << "system_time: " << usage.ru_stime.tv_sec << endl; 558 out << "page_reclaims: " << usage.ru_minflt << endl; 559 out << "page_faults: " << usage.ru_majflt << endl; 560 out << "swaps: " << usage.ru_nswap << endl; 561 out << "block_inputs: " << usage.ru_inblock << endl; 562 out << "block_outputs: " << usage.ru_oublock << endl; 563} 564 565void Profiler::clearStats() 566{ 567 m_ruby_start = g_eventQueue_ptr->getTime(); 568 569 m_cycles_executed_at_start.setSize(RubySystem::getNumberOfSequencers()); 570 for (int i=0; i < RubySystem::getNumberOfSequencers(); i++) { 571 if (g_system_ptr == NULL) { 572 m_cycles_executed_at_start[i] = 0; 573 } else { 574 m_cycles_executed_at_start[i] = g_system_ptr->getCycleCount(i); 575 } 576 } 577 578 m_perProcTotalMisses.setSize(RubySystem::getNumberOfSequencers()); 579 m_perProcUserMisses.setSize(RubySystem::getNumberOfSequencers()); 580 m_perProcSupervisorMisses.setSize(RubySystem::getNumberOfSequencers()); 581 m_perProcStartTransaction.setSize(RubySystem::getNumberOfSequencers()); 582 m_perProcEndTransaction.setSize(RubySystem::getNumberOfSequencers()); 583 584 for(int i=0; i < RubySystem::getNumberOfSequencers(); i++) { 585 m_perProcTotalMisses[i] = 0; 586 m_perProcUserMisses[i] = 0; 587 m_perProcSupervisorMisses[i] = 0; 588 m_perProcStartTransaction[i] = 0; 589 m_perProcEndTransaction[i] = 0; 590 } 591 592 m_busyControllerCount.setSize(MachineType_NUM); // all machines 593 for(int i=0; i < MachineType_NUM; i++) { 594 m_busyControllerCount[i].setSize(MachineType_base_count((MachineType)i)); 595 for(int j=0; j < MachineType_base_count((MachineType)i); j++) { 596 m_busyControllerCount[i][j] = 0; 597 } 598 } 599 m_busyBankCount = 0; 600 601 m_delayedCyclesHistogram.clear(); 602 m_delayedCyclesNonPFHistogram.clear(); 603 m_delayedCyclesVCHistograms.setSize(RubySystem::getNetwork()->getNumberOfVirtualNetworks()); 604 for (int i = 0; i < RubySystem::getNetwork()->getNumberOfVirtualNetworks(); i++) { 605 m_delayedCyclesVCHistograms[i].clear(); 606 } 607 608 m_missLatencyHistograms.setSize(RubyRequestType_NUM); 609 for(int i=0; i<m_missLatencyHistograms.size(); i++) { 610 m_missLatencyHistograms[i].clear(200); 611 } 612 m_machLatencyHistograms.setSize(GenericMachineType_NUM+1); 613 for(int i=0; i<m_machLatencyHistograms.size(); i++) { 614 m_machLatencyHistograms[i].clear(200); 615 } 616 m_allMissLatencyHistogram.clear(200); 617 618 m_SWPrefetchLatencyHistograms.setSize(CacheRequestType_NUM); 619 for(int i=0; i<m_SWPrefetchLatencyHistograms.size(); i++) { 620 m_SWPrefetchLatencyHistograms[i].clear(200); 621 } 622 m_SWPrefetchMachLatencyHistograms.setSize(GenericMachineType_NUM+1); 623 for(int i=0; i<m_SWPrefetchMachLatencyHistograms.size(); i++) { 624 m_SWPrefetchMachLatencyHistograms[i].clear(200); 625 } 626 m_allSWPrefetchLatencyHistogram.clear(200); 627 628 m_sequencer_requests.clear(); 629 m_read_sharing_histogram.clear(); 630 m_write_sharing_histogram.clear(); 631 m_all_sharing_histogram.clear(); 632 m_cache_to_cache = 0; 633 m_memory_to_cache = 0; 634 635 // clear HashMaps 636 m_requestProfileMap_ptr->clear(); 637 638 // count requests profiled 639 m_requests = 0; 640 641 m_outstanding_requests.clear(); 642 m_outstanding_persistent_requests.clear(); 643 644//added by SS 645 vector<string>::iterator it; 646 647 for (int mem_cntrl = 0; 648 mem_cntrl < m_mc_profilers.size(); 649 mem_cntrl++) { 650 m_mc_profilers[mem_cntrl]->m_memReq = 0; 651 m_mc_profilers[mem_cntrl]->m_memBankBusy = 0; 652 m_mc_profilers[mem_cntrl]->m_memBusBusy = 0; 653 m_mc_profilers[mem_cntrl]->m_memTfawBusy = 0; 654 m_mc_profilers[mem_cntrl]->m_memReadWriteBusy = 0; 655 m_mc_profilers[mem_cntrl]->m_memDataBusBusy = 0; 656 m_mc_profilers[mem_cntrl]->m_memRefresh = 0; 657 m_mc_profilers[mem_cntrl]->m_memRead = 0; 658 m_mc_profilers[mem_cntrl]->m_memWrite = 0; 659 m_mc_profilers[mem_cntrl]->m_memWaitCycles = 0; 660 m_mc_profilers[mem_cntrl]->m_memInputQ = 0; 661 m_mc_profilers[mem_cntrl]->m_memBankQ = 0; 662 m_mc_profilers[mem_cntrl]->m_memArbWait = 0; 663 m_mc_profilers[mem_cntrl]->m_memRandBusy = 0; 664 m_mc_profilers[mem_cntrl]->m_memNotOld = 0; 665 666 for (int bank=0; 667 bank < m_mc_profilers[mem_cntrl]->m_memBankCount.size(); 668 bank++) { 669 m_mc_profilers[mem_cntrl]->m_memBankCount[bank] = 0; 670 } 671 } 672 // Flush the prefetches through the system - used so that there are no outstanding requests after stats are cleared 673 //g_eventQueue_ptr->triggerAllEvents(); 674 675 // update the start time 676 m_ruby_start = g_eventQueue_ptr->getTime(); 677} 678 679void Profiler::addAddressTraceSample(const CacheMsg& msg, NodeID id) 680{ 681 if (msg.getType() != CacheRequestType_IFETCH) { 682 683 // Note: The following line should be commented out if you want to 684 // use the special profiling that is part of the GS320 protocol 685 686 // NOTE: Unless PROFILE_HOT_LINES is enabled, nothing will be profiled by the AddressProfiler 687 m_address_profiler_ptr->addTraceSample(msg.getLineAddress(), msg.getProgramCounter(), msg.getType(), msg.getAccessMode(), id, false); 688 } 689} 690 691void Profiler::profileSharing(const Address& addr, AccessType type, NodeID requestor, const Set& sharers, const Set& owner) 692{ 693 Set set_contacted(owner); 694 if (type == AccessType_Write) { 695 set_contacted.addSet(sharers); 696 } 697 set_contacted.remove(requestor); 698 int number_contacted = set_contacted.count(); 699 700 if (type == AccessType_Write) { 701 m_write_sharing_histogram.add(number_contacted); 702 } else { 703 m_read_sharing_histogram.add(number_contacted); 704 } 705 m_all_sharing_histogram.add(number_contacted); 706 707 if (number_contacted == 0) { 708 m_memory_to_cache++; 709 } else { 710 m_cache_to_cache++; 711 } 712 713} 714 715void Profiler::profileMsgDelay(int virtualNetwork, int delayCycles) { 716 assert(virtualNetwork < m_delayedCyclesVCHistograms.size()); 717 m_delayedCyclesHistogram.add(delayCycles); 718 m_delayedCyclesVCHistograms[virtualNetwork].add(delayCycles); 719 if (virtualNetwork != 0) { 720 m_delayedCyclesNonPFHistogram.add(delayCycles); 721 } 722} 723 724// profiles original cache requests including PUTs 725void Profiler::profileRequest(const string& requestStr) 726{ 727 m_requests++; 728 729 if (m_requestProfileMap_ptr->exist(requestStr)) { 730 (m_requestProfileMap_ptr->lookup(requestStr))++; 731 } else { 732 m_requestProfileMap_ptr->add(requestStr, 1); 733 } 734} 735 736void Profiler::startTransaction(int cpu) 737{ 738 m_perProcStartTransaction[cpu]++; 739} 740 741void Profiler::endTransaction(int cpu) 742{ 743 m_perProcEndTransaction[cpu]++; 744} 745 746void Profiler::controllerBusy(MachineID machID) 747{ 748 m_busyControllerCount[(int)machID.type][(int)machID.num]++; 749} 750 751void Profiler::profilePFWait(Time waitTime) 752{ 753 m_prefetchWaitHistogram.add(waitTime); 754} 755 756void Profiler::bankBusy() 757{ 758 m_busyBankCount++; 759} 760 761// non-zero cycle demand request 762void Profiler::missLatency(Time t, RubyRequestType type) 763{ 764 m_allMissLatencyHistogram.add(t); 765 m_missLatencyHistograms[type].add(t); 766} 767 768// non-zero cycle prefetch request 769void Profiler::swPrefetchLatency(Time t, CacheRequestType type, GenericMachineType respondingMach) 770{ 771 m_allSWPrefetchLatencyHistogram.add(t); 772 m_SWPrefetchLatencyHistograms[type].add(t); 773 m_SWPrefetchMachLatencyHistograms[respondingMach].add(t); 774 if(respondingMach == GenericMachineType_Directory || respondingMach == GenericMachineType_NUM) { 775 m_SWPrefetchL2MissLatencyHistogram.add(t); 776 } 777} 778 779void Profiler::profileTransition(const string& component, NodeID version, Address addr, 780 const string& state, const string& event, 781 const string& next_state, const string& note) 782{ 783 const int EVENT_SPACES = 20; 784 const int ID_SPACES = 3; 785 const int TIME_SPACES = 7; 786 const int COMP_SPACES = 10; 787 const int STATE_SPACES = 6; 788 789 if ((g_debug_ptr->getDebugTime() > 0) && 790 (g_eventQueue_ptr->getTime() >= g_debug_ptr->getDebugTime())) { 791 (* debug_cout_ptr).flags(ios::right); 792 (* debug_cout_ptr) << setw(TIME_SPACES) << g_eventQueue_ptr->getTime() << " "; 793 (* debug_cout_ptr) << setw(ID_SPACES) << version << " "; 794 (* debug_cout_ptr) << setw(COMP_SPACES) << component; 795 (* debug_cout_ptr) << setw(EVENT_SPACES) << event << " "; 796 797 (* debug_cout_ptr).flags(ios::right); 798 (* debug_cout_ptr) << setw(STATE_SPACES) << state; 799 (* debug_cout_ptr) << ">"; 800 (* debug_cout_ptr).flags(ios::left); 801 (* debug_cout_ptr) << setw(STATE_SPACES) << next_state; 802 803 (* debug_cout_ptr) << " " << addr << " " << note; 804 805 (* debug_cout_ptr) << endl; 806 } 807} 808 809// Helper function 810static double process_memory_total() 811{ 812 const double MULTIPLIER = 4096.0/(1024.0*1024.0); // 4kB page size, 1024*1024 bytes per MB, 813 ifstream proc_file; 814 proc_file.open("/proc/self/statm"); 815 int total_size_in_pages = 0; 816 int res_size_in_pages = 0; 817 proc_file >> total_size_in_pages; 818 proc_file >> res_size_in_pages; 819 return double(total_size_in_pages)*MULTIPLIER; // size in megabytes 820} 821 822static double process_memory_resident() 823{ 824 const double MULTIPLIER = 4096.0/(1024.0*1024.0); // 4kB page size, 1024*1024 bytes per MB, 825 ifstream proc_file; 826 proc_file.open("/proc/self/statm"); 827 int total_size_in_pages = 0; 828 int res_size_in_pages = 0; 829 proc_file >> total_size_in_pages; 830 proc_file >> res_size_in_pages; 831 return double(res_size_in_pages)*MULTIPLIER; // size in megabytes 832} 833 834void Profiler::rubyWatch(int id){ 835 //int rn_g1 = 0;//SIMICS_get_register_number(id, "g1"); 836 uint64 tr = 0;//SIMICS_read_register(id, rn_g1); 837 Address watch_address = Address(tr); 838 const int ID_SPACES = 3; 839 const int TIME_SPACES = 7; 840 841 (* debug_cout_ptr).flags(ios::right); 842 (* debug_cout_ptr) << setw(TIME_SPACES) << g_eventQueue_ptr->getTime() << " "; 843 (* debug_cout_ptr) << setw(ID_SPACES) << id << " " 844 << "RUBY WATCH " 845 << watch_address 846 << endl; 847 848 if(!m_watch_address_list_ptr->exist(watch_address)){ 849 m_watch_address_list_ptr->add(watch_address, 1); 850 } 851} 852 853bool Profiler::watchAddress(Address addr){ 854 if (m_watch_address_list_ptr->exist(addr)) 855 return true; 856 else 857 return false; 858} 859 860int64 Profiler::getTotalTransactionsExecuted() const { 861 return m_perProcEndTransaction.sum(); 862} 863 864// For MemoryControl: 865void Profiler::profileMemReq(int mem_cntrl, int bank) { 866 m_mc_profilers[mem_cntrl]->m_memReq++; 867 m_mc_profilers[mem_cntrl]->m_memBankCount[bank]++; 868} 869 870void Profiler::profileMemBankBusy(int mem_cntrl) { 871 m_mc_profilers[mem_cntrl]->m_memBankBusy++; 872} 873 874void Profiler::profileMemBusBusy(int mem_cntrl) { 875 m_mc_profilers[mem_cntrl]->m_memBusBusy++; 876} 877 878void Profiler::profileMemReadWriteBusy(int mem_cntrl) { 879 m_mc_profilers[mem_cntrl]->m_memReadWriteBusy++; 880} 881 882void Profiler::profileMemDataBusBusy(int mem_cntrl) { 883 m_mc_profilers[mem_cntrl]->m_memDataBusBusy++; 884} 885 886void Profiler::profileMemTfawBusy(int mem_cntrl) { 887 m_mc_profilers[mem_cntrl]->m_memTfawBusy++; 888} 889 890void Profiler::profileMemRefresh(int mem_cntrl) { 891 m_mc_profilers[mem_cntrl]->m_memRefresh++; 892} 893 894void Profiler::profileMemRead(int mem_cntrl) { 895 m_mc_profilers[mem_cntrl]->m_memRead++; 896} 897 898void Profiler::profileMemWrite(int mem_cntrl) { 899 m_mc_profilers[mem_cntrl]->m_memWrite++; 900} 901 902void Profiler::profileMemWaitCycles(int mem_cntrl, int cycles) { 903 m_mc_profilers[mem_cntrl]->m_memWaitCycles += cycles; 904} 905 906void Profiler::profileMemInputQ(int mem_cntrl, int cycles) { 907 m_mc_profilers[mem_cntrl]->m_memInputQ += cycles; 908} 909 910void Profiler::profileMemBankQ(int mem_cntrl, int cycles) { 911 m_mc_profilers[mem_cntrl]->m_memBankQ += cycles; 912} 913 914void Profiler::profileMemArbWait(int mem_cntrl, int cycles) { 915 m_mc_profilers[mem_cntrl]->m_memArbWait += cycles; 916} 917 918void Profiler::profileMemRandBusy(int mem_cntrl) { 919 m_mc_profilers[mem_cntrl]->m_memRandBusy++; 920} 921 922void Profiler::profileMemNotOld(int mem_cntrl) { 923 m_mc_profilers[mem_cntrl]->m_memNotOld++; 924} 925 926 927Profiler * 928RubyProfilerParams::create() 929{ 930 return new Profiler(this); 931} 932