Profiler.cc revision 9773
16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
36145Snate@binkert.org * All rights reserved.
46145Snate@binkert.org *
56145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
66145Snate@binkert.org * modification, are permitted provided that the following conditions are
76145Snate@binkert.org * met: redistributions of source code must retain the above copyright
86145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
96145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
106145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
116145Snate@binkert.org * documentation and/or other materials provided with the distribution;
126145Snate@binkert.org * neither the name of the copyright holders nor the names of its
136145Snate@binkert.org * contributors may be used to endorse or promote products derived from
146145Snate@binkert.org * this software without specific prior written permission.
156145Snate@binkert.org *
166145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
176145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
186145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
196145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
206145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
236145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
246145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
256145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
266145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276145Snate@binkert.org */
286145Snate@binkert.org
296145Snate@binkert.org/*
306145Snate@binkert.org   This file has been modified by Kevin Moore and Dan Nussbaum of the
316145Snate@binkert.org   Scalable Systems Research Group at Sun Microsystems Laboratories
326145Snate@binkert.org   (http://research.sun.com/scalable/) to support the Adaptive
336145Snate@binkert.org   Transactional Memory Test Platform (ATMTP).
346145Snate@binkert.org
356145Snate@binkert.org   Please send email to atmtp-interest@sun.com with feedback, questions, or
366145Snate@binkert.org   to request future announcements about ATMTP.
376145Snate@binkert.org
386145Snate@binkert.org   ----------------------------------------------------------------------
396145Snate@binkert.org
406145Snate@binkert.org   File modification date: 2008-02-23
416145Snate@binkert.org
426145Snate@binkert.org   ----------------------------------------------------------------------
436145Snate@binkert.org*/
446145Snate@binkert.org
457002Snate@binkert.org// Allows use of times() library call, which determines virtual runtime
467002Snate@binkert.org#include <sys/resource.h>
477002Snate@binkert.org#include <sys/times.h>
488946Sandreas.hansson@arm.com#include <sys/types.h>
498946Sandreas.hansson@arm.com#include <unistd.h>
507002Snate@binkert.org
517454Snate@binkert.org#include <algorithm>
527832Snate@binkert.org#include <fstream>
537454Snate@binkert.org
547454Snate@binkert.org#include "base/stl_helpers.hh"
557056Snate@binkert.org#include "base/str.hh"
567048Snate@binkert.org#include "mem/protocol/MachineType.hh"
578229Snate@binkert.org#include "mem/protocol/RubyRequest.hh"
587048Snate@binkert.org#include "mem/ruby/network/Network.hh"
597048Snate@binkert.org#include "mem/ruby/profiler/AddressProfiler.hh"
606154Snate@binkert.org#include "mem/ruby/profiler/Profiler.hh"
619598Snilay@cs.wisc.edu#include "mem/ruby/system/Sequencer.hh"
626154Snate@binkert.org#include "mem/ruby/system/System.hh"
636876Ssteve.reinhardt@amd.com
647055Snate@binkert.orgusing namespace std;
657454Snate@binkert.orgusing m5::stl_helpers::operator<<;
667055Snate@binkert.org
676145Snate@binkert.orgstatic double process_memory_total();
686145Snate@binkert.orgstatic double process_memory_resident();
696145Snate@binkert.org
706876Ssteve.reinhardt@amd.comProfiler::Profiler(const Params *p)
719746Snilay@cs.wisc.edu    : SimObject(p)
726145Snate@binkert.org{
737048Snate@binkert.org    m_inst_profiler_ptr = NULL;
747048Snate@binkert.org    m_address_profiler_ptr = NULL;
757048Snate@binkert.org    m_real_time_start_time = time(NULL); // Not reset in clearStats()
766145Snate@binkert.org
777048Snate@binkert.org    m_hot_lines = p->hot_lines;
787048Snate@binkert.org    m_all_instructions = p->all_instructions;
796876Ssteve.reinhardt@amd.com
807048Snate@binkert.org    m_num_of_sequencers = p->num_of_sequencers;
816896SBrad.Beckmann@amd.com
827048Snate@binkert.org    m_hot_lines = false;
837048Snate@binkert.org    m_all_instructions = false;
846285Snate@binkert.org
857048Snate@binkert.org    m_address_profiler_ptr = new AddressProfiler(m_num_of_sequencers);
867048Snate@binkert.org    m_address_profiler_ptr->setHotLines(m_hot_lines);
877048Snate@binkert.org    m_address_profiler_ptr->setAllInstructions(m_all_instructions);
886285Snate@binkert.org
897048Snate@binkert.org    if (m_all_instructions) {
907048Snate@binkert.org        m_inst_profiler_ptr = new AddressProfiler(m_num_of_sequencers);
917048Snate@binkert.org        m_inst_profiler_ptr->setHotLines(m_hot_lines);
927048Snate@binkert.org        m_inst_profiler_ptr->setAllInstructions(m_all_instructions);
937048Snate@binkert.org    }
948436SBrad.Beckmann@amd.com
958436SBrad.Beckmann@amd.com    p->ruby_system->registerProfiler(this);
966285Snate@binkert.org}
976285Snate@binkert.org
986889SBrad.Beckmann@amd.comProfiler::~Profiler()
996889SBrad.Beckmann@amd.com{
1007048Snate@binkert.org}
1017048Snate@binkert.org
1027048Snate@binkert.orgvoid
1037048Snate@binkert.orgProfiler::print(ostream& out) const
1047048Snate@binkert.org{
1057048Snate@binkert.org    out << "[Profiler]";
1067048Snate@binkert.org}
1077048Snate@binkert.org
1087048Snate@binkert.orgvoid
1099598Snilay@cs.wisc.eduProfiler::printRequestProfile(ostream &out) const
1109496Snilay@cs.wisc.edu{
1119496Snilay@cs.wisc.edu    out << "Request vs. RubySystem State Profile" << endl;
1129496Snilay@cs.wisc.edu    out << "--------------------------------" << endl;
1139496Snilay@cs.wisc.edu    out << endl;
1149496Snilay@cs.wisc.edu
1159496Snilay@cs.wisc.edu    map<string, uint64_t> m_requestProfileMap;
1169496Snilay@cs.wisc.edu    uint64_t m_requests = 0;
1179496Snilay@cs.wisc.edu
1189496Snilay@cs.wisc.edu    for (uint32_t i = 0; i < MachineType_NUM; i++) {
1199496Snilay@cs.wisc.edu        for (map<uint32_t, AbstractController*>::iterator it =
1209496Snilay@cs.wisc.edu                  g_abs_controls[i].begin();
1219496Snilay@cs.wisc.edu             it != g_abs_controls[i].end(); ++it) {
1229496Snilay@cs.wisc.edu
1239496Snilay@cs.wisc.edu            AbstractController *ctr = (*it).second;
1249496Snilay@cs.wisc.edu            map<string, uint64_t> mp = ctr->getRequestProfileMap();
1259496Snilay@cs.wisc.edu
1269496Snilay@cs.wisc.edu            for (map<string, uint64_t>::iterator jt = mp.begin();
1279496Snilay@cs.wisc.edu                 jt != mp.end(); ++jt) {
1289496Snilay@cs.wisc.edu
1299496Snilay@cs.wisc.edu                map<string, uint64_t>::iterator kt =
1309496Snilay@cs.wisc.edu                    m_requestProfileMap.find((*jt).first);
1319496Snilay@cs.wisc.edu                if (kt != m_requestProfileMap.end()) {
1329496Snilay@cs.wisc.edu                    (*kt).second += (*jt).second;
1339496Snilay@cs.wisc.edu                } else {
1349496Snilay@cs.wisc.edu                    m_requestProfileMap[(*jt).first] = (*jt).second;
1359496Snilay@cs.wisc.edu                }
1369496Snilay@cs.wisc.edu            }
1379496Snilay@cs.wisc.edu
1389496Snilay@cs.wisc.edu            m_requests += ctr->getRequestCount();
1399496Snilay@cs.wisc.edu        }
1409496Snilay@cs.wisc.edu    }
1419496Snilay@cs.wisc.edu
1429496Snilay@cs.wisc.edu    map<string, uint64_t>::const_iterator i = m_requestProfileMap.begin();
1439496Snilay@cs.wisc.edu    map<string, uint64_t>::const_iterator end = m_requestProfileMap.end();
1449496Snilay@cs.wisc.edu    for (; i != end; ++i) {
1459496Snilay@cs.wisc.edu        const string &key = i->first;
1469496Snilay@cs.wisc.edu        uint64_t count = i->second;
1479496Snilay@cs.wisc.edu
1489496Snilay@cs.wisc.edu        double percent = (100.0 * double(count)) / double(m_requests);
1499496Snilay@cs.wisc.edu        vector<string> items;
1509496Snilay@cs.wisc.edu        tokenize(items, key, ':');
1519496Snilay@cs.wisc.edu        vector<string>::iterator j = items.begin();
1529496Snilay@cs.wisc.edu        vector<string>::iterator end = items.end();
1539496Snilay@cs.wisc.edu        for (; j != end; ++i)
1549496Snilay@cs.wisc.edu            out << setw(10) << *j;
1559496Snilay@cs.wisc.edu        out << setw(11) << count;
1569496Snilay@cs.wisc.edu        out << setw(14) << percent << endl;
1579496Snilay@cs.wisc.edu    }
1589496Snilay@cs.wisc.edu    out << endl;
1599496Snilay@cs.wisc.edu}
1609496Snilay@cs.wisc.edu
1619496Snilay@cs.wisc.eduvoid
1629598Snilay@cs.wisc.eduProfiler::printDelayProfile(ostream &out) const
1639497Snilay@cs.wisc.edu{
1649497Snilay@cs.wisc.edu    out << "Message Delayed Cycles" << endl;
1659497Snilay@cs.wisc.edu    out << "----------------------" << endl;
1669497Snilay@cs.wisc.edu
1679497Snilay@cs.wisc.edu    uint32_t numVNets = Network::getNumberOfVirtualNetworks();
1689497Snilay@cs.wisc.edu    Histogram delayHistogram;
1699497Snilay@cs.wisc.edu    std::vector<Histogram> delayVCHistogram(numVNets);
1709497Snilay@cs.wisc.edu
1719497Snilay@cs.wisc.edu    for (uint32_t i = 0; i < MachineType_NUM; i++) {
1729497Snilay@cs.wisc.edu        for (map<uint32_t, AbstractController*>::iterator it =
1739497Snilay@cs.wisc.edu                  g_abs_controls[i].begin();
1749497Snilay@cs.wisc.edu             it != g_abs_controls[i].end(); ++it) {
1759497Snilay@cs.wisc.edu
1769497Snilay@cs.wisc.edu            AbstractController *ctr = (*it).second;
1779497Snilay@cs.wisc.edu            delayHistogram.add(ctr->getDelayHist());
1789497Snilay@cs.wisc.edu
1799497Snilay@cs.wisc.edu            for (uint32_t i = 0; i < numVNets; i++) {
1809497Snilay@cs.wisc.edu                delayVCHistogram[i].add(ctr->getDelayVCHist(i));
1819497Snilay@cs.wisc.edu            }
1829497Snilay@cs.wisc.edu        }
1839497Snilay@cs.wisc.edu    }
1849497Snilay@cs.wisc.edu
1859497Snilay@cs.wisc.edu    out << "Total_delay_cycles: " <<   delayHistogram << endl;
1869497Snilay@cs.wisc.edu
1879497Snilay@cs.wisc.edu    for (int i = 0; i < numVNets; i++) {
1889497Snilay@cs.wisc.edu        out << "  virtual_network_" << i << "_delay_cycles: "
1899497Snilay@cs.wisc.edu            << delayVCHistogram[i] << endl;
1909497Snilay@cs.wisc.edu    }
1919497Snilay@cs.wisc.edu}
1929497Snilay@cs.wisc.edu
1939497Snilay@cs.wisc.eduvoid
1949598Snilay@cs.wisc.eduProfiler::printOutstandingReqProfile(ostream &out) const
1959598Snilay@cs.wisc.edu{
1969598Snilay@cs.wisc.edu    Histogram sequencerRequests;
1979598Snilay@cs.wisc.edu
1989598Snilay@cs.wisc.edu    for (uint32_t i = 0; i < MachineType_NUM; i++) {
1999598Snilay@cs.wisc.edu        for (map<uint32_t, AbstractController*>::iterator it =
2009598Snilay@cs.wisc.edu                  g_abs_controls[i].begin();
2019598Snilay@cs.wisc.edu             it != g_abs_controls[i].end(); ++it) {
2029598Snilay@cs.wisc.edu
2039598Snilay@cs.wisc.edu            AbstractController *ctr = (*it).second;
2049598Snilay@cs.wisc.edu            Sequencer *seq = ctr->getSequencer();
2059598Snilay@cs.wisc.edu            if (seq != NULL) {
2069598Snilay@cs.wisc.edu                sequencerRequests.add(seq->getOutstandReqHist());
2079598Snilay@cs.wisc.edu            }
2089598Snilay@cs.wisc.edu        }
2099598Snilay@cs.wisc.edu    }
2109598Snilay@cs.wisc.edu
2119598Snilay@cs.wisc.edu    out << "sequencer_requests_outstanding: "
2129598Snilay@cs.wisc.edu        << sequencerRequests << endl;
2139598Snilay@cs.wisc.edu}
2149598Snilay@cs.wisc.edu
2159598Snilay@cs.wisc.eduvoid
2169773Snilay@cs.wisc.eduProfiler::printMissLatencyProfile(ostream &out) const
2179773Snilay@cs.wisc.edu{
2189773Snilay@cs.wisc.edu    // Collate the miss latencies histograms from all the sequencers
2199773Snilay@cs.wisc.edu    Histogram latency_hist;
2209773Snilay@cs.wisc.edu    std::vector<Histogram> type_latency_hist(RubyRequestType_NUM);
2219773Snilay@cs.wisc.edu
2229773Snilay@cs.wisc.edu    Histogram hit_latency_hist;
2239773Snilay@cs.wisc.edu    std::vector<Histogram> hit_type_latency_hist(RubyRequestType_NUM);
2249773Snilay@cs.wisc.edu
2259773Snilay@cs.wisc.edu    std::vector<Histogram> hit_mach_latency_hist(MachineType_NUM);
2269773Snilay@cs.wisc.edu    std::vector<std::vector<Histogram> >
2279773Snilay@cs.wisc.edu        hit_type_mach_latency_hist(RubyRequestType_NUM,
2289773Snilay@cs.wisc.edu                               std::vector<Histogram>(MachineType_NUM));
2299773Snilay@cs.wisc.edu
2309773Snilay@cs.wisc.edu    Histogram miss_latency_hist;
2319773Snilay@cs.wisc.edu    std::vector<Histogram> miss_type_latency_hist(RubyRequestType_NUM);
2329773Snilay@cs.wisc.edu
2339773Snilay@cs.wisc.edu    std::vector<Histogram> miss_mach_latency_hist(MachineType_NUM);
2349773Snilay@cs.wisc.edu    std::vector<std::vector<Histogram> >
2359773Snilay@cs.wisc.edu        miss_type_mach_latency_hist(RubyRequestType_NUM,
2369773Snilay@cs.wisc.edu                               std::vector<Histogram>(MachineType_NUM));
2379773Snilay@cs.wisc.edu
2389773Snilay@cs.wisc.edu    std::vector<Histogram> issue_to_initial_delay_hist(MachineType_NUM);
2399773Snilay@cs.wisc.edu    std::vector<Histogram> initial_to_forward_delay_hist(MachineType_NUM);
2409773Snilay@cs.wisc.edu    std::vector<Histogram>
2419773Snilay@cs.wisc.edu        forward_to_first_response_delay_hist(MachineType_NUM);
2429773Snilay@cs.wisc.edu    std::vector<Histogram>
2439773Snilay@cs.wisc.edu        first_response_to_completion_delay_hist(MachineType_NUM);
2449773Snilay@cs.wisc.edu    std::vector<uint64_t> incomplete_times(MachineType_NUM);
2459773Snilay@cs.wisc.edu
2469773Snilay@cs.wisc.edu    for (uint32_t i = 0; i < MachineType_NUM; i++) {
2479773Snilay@cs.wisc.edu        for (map<uint32_t, AbstractController*>::iterator it =
2489773Snilay@cs.wisc.edu                  g_abs_controls[i].begin();
2499773Snilay@cs.wisc.edu             it != g_abs_controls[i].end(); ++it) {
2509773Snilay@cs.wisc.edu
2519773Snilay@cs.wisc.edu            AbstractController *ctr = (*it).second;
2529773Snilay@cs.wisc.edu            Sequencer *seq = ctr->getSequencer();
2539773Snilay@cs.wisc.edu            if (seq != NULL) {
2549773Snilay@cs.wisc.edu                // add all the latencies
2559773Snilay@cs.wisc.edu                latency_hist.add(seq->getLatencyHist());
2569773Snilay@cs.wisc.edu                hit_latency_hist.add(seq->getHitLatencyHist());
2579773Snilay@cs.wisc.edu                miss_latency_hist.add(seq->getMissLatencyHist());
2589773Snilay@cs.wisc.edu
2599773Snilay@cs.wisc.edu                // add the per request type latencies
2609773Snilay@cs.wisc.edu                for (uint32_t j = 0; j < RubyRequestType_NUM; ++j) {
2619773Snilay@cs.wisc.edu                    type_latency_hist[j]
2629773Snilay@cs.wisc.edu                        .add(seq->getTypeLatencyHist(j));
2639773Snilay@cs.wisc.edu                    hit_type_latency_hist[j]
2649773Snilay@cs.wisc.edu                        .add(seq->getHitTypeLatencyHist(j));
2659773Snilay@cs.wisc.edu                    miss_type_latency_hist[j]
2669773Snilay@cs.wisc.edu                        .add(seq->getMissTypeLatencyHist(j));
2679773Snilay@cs.wisc.edu                }
2689773Snilay@cs.wisc.edu
2699773Snilay@cs.wisc.edu                // add the per machine type miss latencies
2709773Snilay@cs.wisc.edu                for (uint32_t j = 0; j < MachineType_NUM; ++j) {
2719773Snilay@cs.wisc.edu                    hit_mach_latency_hist[j]
2729773Snilay@cs.wisc.edu                        .add(seq->getHitMachLatencyHist(j));
2739773Snilay@cs.wisc.edu                    miss_mach_latency_hist[j]
2749773Snilay@cs.wisc.edu                        .add(seq->getMissMachLatencyHist(j));
2759773Snilay@cs.wisc.edu
2769773Snilay@cs.wisc.edu                    issue_to_initial_delay_hist[j].add(
2779773Snilay@cs.wisc.edu                        seq->getIssueToInitialDelayHist(MachineType(j)));
2789773Snilay@cs.wisc.edu
2799773Snilay@cs.wisc.edu                    initial_to_forward_delay_hist[j].add(
2809773Snilay@cs.wisc.edu                        seq->getInitialToForwardDelayHist(MachineType(j)));
2819773Snilay@cs.wisc.edu                    forward_to_first_response_delay_hist[j].add(seq->
2829773Snilay@cs.wisc.edu                        getForwardRequestToFirstResponseHist(MachineType(j)));
2839773Snilay@cs.wisc.edu
2849773Snilay@cs.wisc.edu                    first_response_to_completion_delay_hist[j].add(seq->
2859773Snilay@cs.wisc.edu                        getFirstResponseToCompletionDelayHist(MachineType(j)));
2869773Snilay@cs.wisc.edu                    incomplete_times[j] +=
2879773Snilay@cs.wisc.edu                        seq->getIncompleteTimes(MachineType(j));
2889773Snilay@cs.wisc.edu                }
2899773Snilay@cs.wisc.edu
2909773Snilay@cs.wisc.edu                // add the per (request, machine) type miss latencies
2919773Snilay@cs.wisc.edu                for (uint32_t j = 0; j < RubyRequestType_NUM; j++) {
2929773Snilay@cs.wisc.edu                    for (uint32_t k = 0; k < MachineType_NUM; k++) {
2939773Snilay@cs.wisc.edu                        hit_type_mach_latency_hist[j][k].add(
2949773Snilay@cs.wisc.edu                            seq->getHitTypeMachLatencyHist(j,k));
2959773Snilay@cs.wisc.edu                        miss_type_mach_latency_hist[j][k].add(
2969773Snilay@cs.wisc.edu                            seq->getMissTypeMachLatencyHist(j,k));
2979773Snilay@cs.wisc.edu                    }
2989773Snilay@cs.wisc.edu                }
2999773Snilay@cs.wisc.edu            }
3009773Snilay@cs.wisc.edu        }
3019773Snilay@cs.wisc.edu    }
3029773Snilay@cs.wisc.edu
3039773Snilay@cs.wisc.edu    out << "latency: " << latency_hist << endl;
3049773Snilay@cs.wisc.edu    for (int i = 0; i < RubyRequestType_NUM; i++) {
3059773Snilay@cs.wisc.edu        if (type_latency_hist[i].size() > 0) {
3069773Snilay@cs.wisc.edu            out << "latency: " << RubyRequestType(i) << ": "
3079773Snilay@cs.wisc.edu                << type_latency_hist[i] << endl;
3089773Snilay@cs.wisc.edu        }
3099773Snilay@cs.wisc.edu    }
3109773Snilay@cs.wisc.edu
3119773Snilay@cs.wisc.edu    out << "hit latency: " << hit_latency_hist << endl;
3129773Snilay@cs.wisc.edu    for (int i = 0; i < RubyRequestType_NUM; i++) {
3139773Snilay@cs.wisc.edu        if (hit_type_latency_hist[i].size() > 0) {
3149773Snilay@cs.wisc.edu            out << "hit latency: " << RubyRequestType(i) << ": "
3159773Snilay@cs.wisc.edu                << hit_type_latency_hist[i] << endl;
3169773Snilay@cs.wisc.edu        }
3179773Snilay@cs.wisc.edu    }
3189773Snilay@cs.wisc.edu
3199773Snilay@cs.wisc.edu    for (int i = 0; i < MachineType_NUM; i++) {
3209773Snilay@cs.wisc.edu        if (hit_mach_latency_hist[i].size() > 0) {
3219773Snilay@cs.wisc.edu            out << "hit latency: " << MachineType(i) << ": "
3229773Snilay@cs.wisc.edu                << hit_mach_latency_hist[i] << endl;
3239773Snilay@cs.wisc.edu        }
3249773Snilay@cs.wisc.edu    }
3259773Snilay@cs.wisc.edu
3269773Snilay@cs.wisc.edu    for (int i = 0; i < RubyRequestType_NUM; i++) {
3279773Snilay@cs.wisc.edu        for (int j = 0; j < MachineType_NUM; j++) {
3289773Snilay@cs.wisc.edu            if (hit_type_mach_latency_hist[i][j].size() > 0) {
3299773Snilay@cs.wisc.edu                out << "hit latency: " << RubyRequestType(i)
3309773Snilay@cs.wisc.edu                    << ": " << MachineType(j) << ": "
3319773Snilay@cs.wisc.edu                    << hit_type_mach_latency_hist[i][j] << endl;
3329773Snilay@cs.wisc.edu            }
3339773Snilay@cs.wisc.edu        }
3349773Snilay@cs.wisc.edu    }
3359773Snilay@cs.wisc.edu
3369773Snilay@cs.wisc.edu    out << "miss latency: " << miss_latency_hist << endl;
3379773Snilay@cs.wisc.edu    for (int i = 0; i < RubyRequestType_NUM; i++) {
3389773Snilay@cs.wisc.edu        if (miss_type_latency_hist[i].size() > 0) {
3399773Snilay@cs.wisc.edu            out << "miss latency: " << RubyRequestType(i) << ": "
3409773Snilay@cs.wisc.edu                << miss_type_latency_hist[i] << endl;
3419773Snilay@cs.wisc.edu        }
3429773Snilay@cs.wisc.edu    }
3439773Snilay@cs.wisc.edu
3449773Snilay@cs.wisc.edu    for (int i = 0; i < MachineType_NUM; i++) {
3459773Snilay@cs.wisc.edu        if (miss_mach_latency_hist[i].size() > 0) {
3469773Snilay@cs.wisc.edu            out << "miss latency: " << MachineType(i) << ": "
3479773Snilay@cs.wisc.edu                << miss_mach_latency_hist[i] << endl;
3489773Snilay@cs.wisc.edu
3499773Snilay@cs.wisc.edu            out << "miss latency: " << MachineType(i)
3509773Snilay@cs.wisc.edu                << "::issue_to_initial_request: "
3519773Snilay@cs.wisc.edu                << issue_to_initial_delay_hist[i] << endl;
3529773Snilay@cs.wisc.edu            out << "miss latency: " << MachineType(i)
3539773Snilay@cs.wisc.edu                << "::initial_to_forward_request: "
3549773Snilay@cs.wisc.edu                << initial_to_forward_delay_hist[i] << endl;
3559773Snilay@cs.wisc.edu            out << "miss latency: " << MachineType(i)
3569773Snilay@cs.wisc.edu                << "::forward_to_first_response: "
3579773Snilay@cs.wisc.edu                << forward_to_first_response_delay_hist[i] << endl;
3589773Snilay@cs.wisc.edu            out << "miss latency: " << MachineType(i)
3599773Snilay@cs.wisc.edu                << "::first_response_to_completion: "
3609773Snilay@cs.wisc.edu                << first_response_to_completion_delay_hist[i] << endl;
3619773Snilay@cs.wisc.edu            out << "incomplete times: " << incomplete_times[i] << endl;
3629773Snilay@cs.wisc.edu        }
3639773Snilay@cs.wisc.edu    }
3649773Snilay@cs.wisc.edu
3659773Snilay@cs.wisc.edu    for (int i = 0; i < RubyRequestType_NUM; i++) {
3669773Snilay@cs.wisc.edu        for (int j = 0; j < MachineType_NUM; j++) {
3679773Snilay@cs.wisc.edu            if (miss_type_mach_latency_hist[i][j].size() > 0) {
3689773Snilay@cs.wisc.edu                out << "miss latency: " << RubyRequestType(i)
3699773Snilay@cs.wisc.edu                    << ": " << MachineType(j) << ": "
3709773Snilay@cs.wisc.edu                    << miss_type_mach_latency_hist[i][j] << endl;
3719773Snilay@cs.wisc.edu            }
3729773Snilay@cs.wisc.edu        }
3739773Snilay@cs.wisc.edu    }
3749773Snilay@cs.wisc.edu
3759773Snilay@cs.wisc.edu    out << endl;
3769773Snilay@cs.wisc.edu}
3779773Snilay@cs.wisc.edu
3789773Snilay@cs.wisc.eduvoid
3797048Snate@binkert.orgProfiler::printStats(ostream& out, bool short_stats)
3807048Snate@binkert.org{
3817048Snate@binkert.org    out << endl;
3827048Snate@binkert.org    if (short_stats) {
3837048Snate@binkert.org        out << "SHORT ";
3847048Snate@binkert.org    }
3857048Snate@binkert.org    out << "Profiler Stats" << endl;
3867048Snate@binkert.org    out << "--------------" << endl;
3877048Snate@binkert.org
3887048Snate@binkert.org    time_t real_time_current = time(NULL);
3897048Snate@binkert.org    double seconds = difftime(real_time_current, m_real_time_start_time);
3907048Snate@binkert.org    double minutes = seconds / 60.0;
3917048Snate@binkert.org    double hours = minutes / 60.0;
3927048Snate@binkert.org    double days = hours / 24.0;
3939508Snilay@cs.wisc.edu    Cycles ruby_cycles = g_system_ptr->curCycle()-m_ruby_start;
3947048Snate@binkert.org
3957048Snate@binkert.org    if (!short_stats) {
3967048Snate@binkert.org        out << "Elapsed_time_in_seconds: " << seconds << endl;
3977048Snate@binkert.org        out << "Elapsed_time_in_minutes: " << minutes << endl;
3987048Snate@binkert.org        out << "Elapsed_time_in_hours: " << hours << endl;
3997048Snate@binkert.org        out << "Elapsed_time_in_days: " << days << endl;
4007048Snate@binkert.org        out << endl;
4017048Snate@binkert.org    }
4027048Snate@binkert.org
4037048Snate@binkert.org    // print the virtual runtimes as well
4047048Snate@binkert.org    struct tms vtime;
4057048Snate@binkert.org    times(&vtime);
4067048Snate@binkert.org    seconds = (vtime.tms_utime + vtime.tms_stime) / 100.0;
4077048Snate@binkert.org    minutes = seconds / 60.0;
4087048Snate@binkert.org    hours = minutes / 60.0;
4097048Snate@binkert.org    days = hours / 24.0;
4107048Snate@binkert.org    out << "Virtual_time_in_seconds: " << seconds << endl;
4117048Snate@binkert.org    out << "Virtual_time_in_minutes: " << minutes << endl;
4127048Snate@binkert.org    out << "Virtual_time_in_hours:   " << hours << endl;
4137048Snate@binkert.org    out << "Virtual_time_in_days:    " << days << endl;
4146145Snate@binkert.org    out << endl;
4156145Snate@binkert.org
4169508Snilay@cs.wisc.edu    out << "Ruby_current_time: " << g_system_ptr->curCycle() << endl;
4177048Snate@binkert.org    out << "Ruby_start_time: " << m_ruby_start << endl;
4187048Snate@binkert.org    out << "Ruby_cycles: " << ruby_cycles << endl;
4196145Snate@binkert.org    out << endl;
4206145Snate@binkert.org
4217048Snate@binkert.org    if (!short_stats) {
4227048Snate@binkert.org        out << "mbytes_resident: " << process_memory_resident() << endl;
4237048Snate@binkert.org        out << "mbytes_total: " << process_memory_total() << endl;
4247048Snate@binkert.org        if (process_memory_total() > 0) {
4257054Snate@binkert.org            out << "resident_ratio: "
4267048Snate@binkert.org                << process_memory_resident()/process_memory_total() << endl;
4277048Snate@binkert.org        }
4287048Snate@binkert.org        out << endl;
4296145Snate@binkert.org    }
4306145Snate@binkert.org
4317048Snate@binkert.org    if (!short_stats) {
4327048Snate@binkert.org        out << "Busy Controller Counts:" << endl;
4339496Snilay@cs.wisc.edu        for (uint32_t i = 0; i < MachineType_NUM; i++) {
4349496Snilay@cs.wisc.edu            uint32_t size = MachineType_base_count((MachineType)i);
4359496Snilay@cs.wisc.edu
4369496Snilay@cs.wisc.edu            for (uint32_t j = 0; j < size; j++) {
4377048Snate@binkert.org                MachineID machID;
4387048Snate@binkert.org                machID.type = (MachineType)i;
4397048Snate@binkert.org                machID.num = j;
4409496Snilay@cs.wisc.edu
4419496Snilay@cs.wisc.edu                AbstractController *ctr =
4429496Snilay@cs.wisc.edu                    (*(g_abs_controls[i].find(j))).second;
4439496Snilay@cs.wisc.edu                out << machID << ":" << ctr->getFullyBusyCycles() << "  ";
4447048Snate@binkert.org                if ((j + 1) % 8 == 0) {
4457048Snate@binkert.org                    out << endl;
4467048Snate@binkert.org                }
4477048Snate@binkert.org            }
4487048Snate@binkert.org            out << endl;
4497048Snate@binkert.org        }
4507048Snate@binkert.org        out << endl;
4517048Snate@binkert.org
4527048Snate@binkert.org        out << "Busy Bank Count:" << m_busyBankCount << endl;
4537048Snate@binkert.org        out << endl;
4547048Snate@binkert.org
4559598Snilay@cs.wisc.edu        printOutstandingReqProfile(out);
4567048Snate@binkert.org        out << endl;
4576145Snate@binkert.org    }
4586145Snate@binkert.org
4597048Snate@binkert.org    if (!short_stats) {
4607048Snate@binkert.org        out << "All Non-Zero Cycle Demand Cache Accesses" << endl;
4617048Snate@binkert.org        out << "----------------------------------------" << endl;
4629773Snilay@cs.wisc.edu        printMissLatencyProfile(out);
4637048Snate@binkert.org
4647048Snate@binkert.org        if (m_all_sharing_histogram.size() > 0) {
4657048Snate@binkert.org            out << "all_sharing: " << m_all_sharing_histogram << endl;
4667048Snate@binkert.org            out << "read_sharing: " << m_read_sharing_histogram << endl;
4677048Snate@binkert.org            out << "write_sharing: " << m_write_sharing_histogram << endl;
4687048Snate@binkert.org
4697048Snate@binkert.org            out << "all_sharing_percent: ";
4707048Snate@binkert.org            m_all_sharing_histogram.printPercent(out);
4717048Snate@binkert.org            out << endl;
4727048Snate@binkert.org
4737048Snate@binkert.org            out << "read_sharing_percent: ";
4747048Snate@binkert.org            m_read_sharing_histogram.printPercent(out);
4757048Snate@binkert.org            out << endl;
4767048Snate@binkert.org
4777048Snate@binkert.org            out << "write_sharing_percent: ";
4787048Snate@binkert.org            m_write_sharing_histogram.printPercent(out);
4797048Snate@binkert.org            out << endl;
4807048Snate@binkert.org
4817048Snate@binkert.org            int64 total_miss = m_cache_to_cache +  m_memory_to_cache;
4827048Snate@binkert.org            out << "all_misses: " << total_miss << endl;
4837048Snate@binkert.org            out << "cache_to_cache_misses: " << m_cache_to_cache << endl;
4847048Snate@binkert.org            out << "memory_to_cache_misses: " << m_memory_to_cache << endl;
4857048Snate@binkert.org            out << "cache_to_cache_percent: "
4867048Snate@binkert.org                << 100.0 * (double(m_cache_to_cache) / double(total_miss))
4877048Snate@binkert.org                << endl;
4887048Snate@binkert.org            out << "memory_to_cache_percent: "
4897048Snate@binkert.org                << 100.0 * (double(m_memory_to_cache) / double(total_miss))
4907048Snate@binkert.org                << endl;
4917048Snate@binkert.org            out << endl;
4927048Snate@binkert.org        }
4937048Snate@binkert.org
4949496Snilay@cs.wisc.edu        printRequestProfile(out);
4957048Snate@binkert.org
4967048Snate@binkert.org        if (!m_all_instructions) {
4977048Snate@binkert.org            m_address_profiler_ptr->printStats(out);
4987048Snate@binkert.org        }
4997048Snate@binkert.org
5007048Snate@binkert.org        if (m_all_instructions) {
5017048Snate@binkert.org            m_inst_profiler_ptr->printStats(out);
5027048Snate@binkert.org        }
5037048Snate@binkert.org
5047048Snate@binkert.org        out << endl;
5059497Snilay@cs.wisc.edu        printDelayProfile(out);
5067048Snate@binkert.org        printResourceUsage(out);
5077048Snate@binkert.org    }
5086145Snate@binkert.org}
5096145Snate@binkert.org
5107048Snate@binkert.orgvoid
5117048Snate@binkert.orgProfiler::printResourceUsage(ostream& out) const
5126145Snate@binkert.org{
5137048Snate@binkert.org    out << endl;
5147048Snate@binkert.org    out << "Resource Usage" << endl;
5157048Snate@binkert.org    out << "--------------" << endl;
5166145Snate@binkert.org
5179231Snilay@cs.wisc.edu    int64_t pagesize = getpagesize(); // page size in bytes
5187048Snate@binkert.org    out << "page_size: " << pagesize << endl;
5196145Snate@binkert.org
5207048Snate@binkert.org    rusage usage;
5217048Snate@binkert.org    getrusage (RUSAGE_SELF, &usage);
5226145Snate@binkert.org
5237048Snate@binkert.org    out << "user_time: " << usage.ru_utime.tv_sec << endl;
5247048Snate@binkert.org    out << "system_time: " << usage.ru_stime.tv_sec << endl;
5257048Snate@binkert.org    out << "page_reclaims: " << usage.ru_minflt << endl;
5267048Snate@binkert.org    out << "page_faults: " << usage.ru_majflt << endl;
5277048Snate@binkert.org    out << "swaps: " << usage.ru_nswap << endl;
5287048Snate@binkert.org    out << "block_inputs: " << usage.ru_inblock << endl;
5297048Snate@binkert.org    out << "block_outputs: " << usage.ru_oublock << endl;
5306145Snate@binkert.org}
5316145Snate@binkert.org
5327048Snate@binkert.orgvoid
5337048Snate@binkert.orgProfiler::clearStats()
5346145Snate@binkert.org{
5359508Snilay@cs.wisc.edu    m_ruby_start = g_system_ptr->curCycle();
5369350Skhaleghzadeh@gmail.com    m_real_time_start_time = time(NULL);
5376145Snate@binkert.org
5387048Snate@binkert.org    m_busyBankCount = 0;
5397048Snate@binkert.org    m_read_sharing_histogram.clear();
5407048Snate@binkert.org    m_write_sharing_histogram.clear();
5417048Snate@binkert.org    m_all_sharing_histogram.clear();
5427048Snate@binkert.org    m_cache_to_cache = 0;
5437048Snate@binkert.org    m_memory_to_cache = 0;
5446145Snate@binkert.org
5457048Snate@binkert.org    // update the start time
5469508Snilay@cs.wisc.edu    m_ruby_start = g_system_ptr->curCycle();
5476145Snate@binkert.org}
5486145Snate@binkert.org
5497048Snate@binkert.orgvoid
5508174Snilay@cs.wisc.eduProfiler::addAddressTraceSample(const RubyRequest& msg, NodeID id)
5516145Snate@binkert.org{
5528165Snilay@cs.wisc.edu    if (msg.getType() != RubyRequestType_IFETCH) {
5537048Snate@binkert.org        // Note: The following line should be commented out if you
5547048Snate@binkert.org        // want to use the special profiling that is part of the GS320
5557048Snate@binkert.org        // protocol
5566145Snate@binkert.org
5577048Snate@binkert.org        // NOTE: Unless PROFILE_HOT_LINES is enabled, nothing will be
5587048Snate@binkert.org        // profiled by the AddressProfiler
5597048Snate@binkert.org        m_address_profiler_ptr->
5607048Snate@binkert.org            addTraceSample(msg.getLineAddress(), msg.getProgramCounter(),
5617048Snate@binkert.org                           msg.getType(), msg.getAccessMode(), id, false);
5627048Snate@binkert.org    }
5636145Snate@binkert.org}
5646145Snate@binkert.org
5657048Snate@binkert.orgvoid
5667048Snate@binkert.orgProfiler::profileSharing(const Address& addr, AccessType type,
5677048Snate@binkert.org                         NodeID requestor, const Set& sharers,
5687048Snate@binkert.org                         const Set& owner)
5696145Snate@binkert.org{
5707048Snate@binkert.org    Set set_contacted(owner);
5717048Snate@binkert.org    if (type == AccessType_Write) {
5727048Snate@binkert.org        set_contacted.addSet(sharers);
5737048Snate@binkert.org    }
5747048Snate@binkert.org    set_contacted.remove(requestor);
5757048Snate@binkert.org    int number_contacted = set_contacted.count();
5766145Snate@binkert.org
5777048Snate@binkert.org    if (type == AccessType_Write) {
5787048Snate@binkert.org        m_write_sharing_histogram.add(number_contacted);
5797048Snate@binkert.org    } else {
5807048Snate@binkert.org        m_read_sharing_histogram.add(number_contacted);
5817048Snate@binkert.org    }
5827048Snate@binkert.org    m_all_sharing_histogram.add(number_contacted);
5836145Snate@binkert.org
5847048Snate@binkert.org    if (number_contacted == 0) {
5857048Snate@binkert.org        m_memory_to_cache++;
5867048Snate@binkert.org    } else {
5877048Snate@binkert.org        m_cache_to_cache++;
5887048Snate@binkert.org    }
5896145Snate@binkert.org}
5906145Snate@binkert.org
5917048Snate@binkert.orgvoid
5927048Snate@binkert.orgProfiler::bankBusy()
5936145Snate@binkert.org{
5947048Snate@binkert.org    m_busyBankCount++;
5956145Snate@binkert.org}
5966145Snate@binkert.org
5976145Snate@binkert.org// Helper function
5987048Snate@binkert.orgstatic double
5997048Snate@binkert.orgprocess_memory_total()
6006145Snate@binkert.org{
6017048Snate@binkert.org    // 4kB page size, 1024*1024 bytes per MB,
6027054Snate@binkert.org    const double MULTIPLIER = 4096.0 / (1024.0 * 1024.0);
6037048Snate@binkert.org    ifstream proc_file;
6047048Snate@binkert.org    proc_file.open("/proc/self/statm");
6057048Snate@binkert.org    int total_size_in_pages = 0;
6067048Snate@binkert.org    int res_size_in_pages = 0;
6077048Snate@binkert.org    proc_file >> total_size_in_pages;
6087048Snate@binkert.org    proc_file >> res_size_in_pages;
6097048Snate@binkert.org    return double(total_size_in_pages) * MULTIPLIER; // size in megabytes
6106145Snate@binkert.org}
6116145Snate@binkert.org
6127048Snate@binkert.orgstatic double
6137048Snate@binkert.orgprocess_memory_resident()
6146145Snate@binkert.org{
6157048Snate@binkert.org    // 4kB page size, 1024*1024 bytes per MB,
6167048Snate@binkert.org    const double MULTIPLIER = 4096.0 / (1024.0 * 1024.0);
6177048Snate@binkert.org    ifstream proc_file;
6187048Snate@binkert.org    proc_file.open("/proc/self/statm");
6197048Snate@binkert.org    int total_size_in_pages = 0;
6207048Snate@binkert.org    int res_size_in_pages = 0;
6217048Snate@binkert.org    proc_file >> total_size_in_pages;
6227048Snate@binkert.org    proc_file >> res_size_in_pages;
6237048Snate@binkert.org    return double(res_size_in_pages) * MULTIPLIER; // size in megabytes
6246145Snate@binkert.org}
6256145Snate@binkert.org
6267048Snate@binkert.orgvoid
6277048Snate@binkert.orgProfiler::rubyWatch(int id)
6287048Snate@binkert.org{
6297010SBrad.Beckmann@amd.com    uint64 tr = 0;
6306285Snate@binkert.org    Address watch_address = Address(tr);
6316285Snate@binkert.org
6329508Snilay@cs.wisc.edu    DPRINTFN("%7s %3s RUBY WATCH %d\n", g_system_ptr->curCycle(), id,
6337832Snate@binkert.org        watch_address);
6347048Snate@binkert.org
6357455Snate@binkert.org    // don't care about success or failure
6367455Snate@binkert.org    m_watch_address_set.insert(watch_address);
6376285Snate@binkert.org}
6386285Snate@binkert.org
6397048Snate@binkert.orgbool
6407048Snate@binkert.orgProfiler::watchAddress(Address addr)
6417048Snate@binkert.org{
6427455Snate@binkert.org    return m_watch_address_set.count(addr) > 0;
6436285Snate@binkert.org}
6446285Snate@binkert.org
6456876Ssteve.reinhardt@amd.comProfiler *
6466876Ssteve.reinhardt@amd.comRubyProfilerParams::create()
6476876Ssteve.reinhardt@amd.com{
6486876Ssteve.reinhardt@amd.com    return new Profiler(this);
6496876Ssteve.reinhardt@amd.com}
650