Profiler.cc revision 7454
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>
487002Snate@binkert.org
497454Snate@binkert.org#include <algorithm>
507454Snate@binkert.org
517454Snate@binkert.org#include "base/stl_helpers.hh"
527056Snate@binkert.org#include "base/str.hh"
537048Snate@binkert.org#include "mem/gems_common/Map.hh"
547048Snate@binkert.org#include "mem/gems_common/PrioHeap.hh"
557048Snate@binkert.org#include "mem/protocol/CacheMsg.hh"
567048Snate@binkert.org#include "mem/protocol/MachineType.hh"
577048Snate@binkert.org#include "mem/protocol/Protocol.hh"
587048Snate@binkert.org#include "mem/ruby/common/Debug.hh"
597048Snate@binkert.org#include "mem/ruby/network/Network.hh"
607048Snate@binkert.org#include "mem/ruby/profiler/AddressProfiler.hh"
616154Snate@binkert.org#include "mem/ruby/profiler/Profiler.hh"
626154Snate@binkert.org#include "mem/ruby/system/System.hh"
636876Ssteve.reinhardt@amd.com#include "mem/ruby/system/System.hh"
646876Ssteve.reinhardt@amd.com
657055Snate@binkert.orgusing namespace std;
667454Snate@binkert.orgusing m5::stl_helpers::operator<<;
677055Snate@binkert.org
687055Snate@binkert.orgextern ostream* debug_cout_ptr;
696145Snate@binkert.org
706145Snate@binkert.orgstatic double process_memory_total();
716145Snate@binkert.orgstatic double process_memory_resident();
726145Snate@binkert.org
736876Ssteve.reinhardt@amd.comProfiler::Profiler(const Params *p)
746876Ssteve.reinhardt@amd.com    : SimObject(p)
756145Snate@binkert.org{
767048Snate@binkert.org    m_requestProfileMap_ptr = new Map<string, int>;
776145Snate@binkert.org
787048Snate@binkert.org    m_inst_profiler_ptr = NULL;
797048Snate@binkert.org    m_address_profiler_ptr = NULL;
806285Snate@binkert.org
817048Snate@binkert.org    m_real_time_start_time = time(NULL); // Not reset in clearStats()
827048Snate@binkert.org    m_stats_period = 1000000; // Default
837048Snate@binkert.org    m_periodic_output_file_ptr = &cerr;
846145Snate@binkert.org
857048Snate@binkert.org    m_hot_lines = p->hot_lines;
867048Snate@binkert.org    m_all_instructions = p->all_instructions;
876876Ssteve.reinhardt@amd.com
887048Snate@binkert.org    m_num_of_sequencers = p->num_of_sequencers;
896896SBrad.Beckmann@amd.com
907048Snate@binkert.org    m_hot_lines = false;
917048Snate@binkert.org    m_all_instructions = false;
926285Snate@binkert.org
937048Snate@binkert.org    m_address_profiler_ptr = new AddressProfiler(m_num_of_sequencers);
947048Snate@binkert.org    m_address_profiler_ptr->setHotLines(m_hot_lines);
957048Snate@binkert.org    m_address_profiler_ptr->setAllInstructions(m_all_instructions);
966285Snate@binkert.org
977048Snate@binkert.org    if (m_all_instructions) {
987048Snate@binkert.org        m_inst_profiler_ptr = new AddressProfiler(m_num_of_sequencers);
997048Snate@binkert.org        m_inst_profiler_ptr->setHotLines(m_hot_lines);
1007048Snate@binkert.org        m_inst_profiler_ptr->setAllInstructions(m_all_instructions);
1017048Snate@binkert.org    }
1026285Snate@binkert.org}
1036285Snate@binkert.org
1046889SBrad.Beckmann@amd.comProfiler::~Profiler()
1056889SBrad.Beckmann@amd.com{
1067048Snate@binkert.org    if (m_periodic_output_file_ptr != &cerr) {
1077048Snate@binkert.org        delete m_periodic_output_file_ptr;
1087048Snate@binkert.org    }
1096889SBrad.Beckmann@amd.com
1107048Snate@binkert.org    delete m_requestProfileMap_ptr;
1116889SBrad.Beckmann@amd.com}
1126889SBrad.Beckmann@amd.com
1137048Snate@binkert.orgvoid
1147048Snate@binkert.orgProfiler::wakeup()
1156145Snate@binkert.org{
1167048Snate@binkert.org    // FIXME - avoid the repeated code
1176145Snate@binkert.org
1187454Snate@binkert.org    vector<integer_t> perProcCycleCount(m_num_of_sequencers);
1196145Snate@binkert.org
1207048Snate@binkert.org    for (int i = 0; i < m_num_of_sequencers; i++) {
1217048Snate@binkert.org        perProcCycleCount[i] =
1227048Snate@binkert.org            g_system_ptr->getCycleCount(i) - m_cycles_executed_at_start[i] + 1;
1237048Snate@binkert.org        // The +1 allows us to avoid division by zero
1247048Snate@binkert.org    }
1256145Snate@binkert.org
1267048Snate@binkert.org    ostream &out = *m_periodic_output_file_ptr;
1276889SBrad.Beckmann@amd.com
1287048Snate@binkert.org    out << "ruby_cycles: " << g_eventQueue_ptr->getTime()-m_ruby_start << endl
1297048Snate@binkert.org        << "mbytes_resident: " << process_memory_resident() << endl
1307048Snate@binkert.org        << "mbytes_total: " << process_memory_total() << endl;
1316889SBrad.Beckmann@amd.com
1327048Snate@binkert.org    if (process_memory_total() > 0) {
1337054Snate@binkert.org        out << "resident_ratio: "
1347048Snate@binkert.org            << process_memory_resident() / process_memory_total() << endl;
1357048Snate@binkert.org    }
1366889SBrad.Beckmann@amd.com
1376145Snate@binkert.org    out << "miss_latency: " << m_allMissLatencyHistogram << endl;
1386145Snate@binkert.org
1396145Snate@binkert.org    out << endl;
1406145Snate@binkert.org
1417048Snate@binkert.org    if (m_all_instructions) {
1427048Snate@binkert.org        m_inst_profiler_ptr->printStats(out);
1436145Snate@binkert.org    }
1446145Snate@binkert.org
1457048Snate@binkert.org    //g_system_ptr->getNetwork()->printStats(out);
1467048Snate@binkert.org    g_eventQueue_ptr->scheduleEvent(this, m_stats_period);
1477048Snate@binkert.org}
1487048Snate@binkert.org
1497048Snate@binkert.orgvoid
1507048Snate@binkert.orgProfiler::setPeriodicStatsFile(const string& filename)
1517048Snate@binkert.org{
1527048Snate@binkert.org    cout << "Recording periodic statistics to file '" << filename << "' every "
1537048Snate@binkert.org         << m_stats_period << " Ruby cycles" << endl;
1547048Snate@binkert.org
1557048Snate@binkert.org    if (m_periodic_output_file_ptr != &cerr) {
1567048Snate@binkert.org        delete m_periodic_output_file_ptr;
1576145Snate@binkert.org    }
1586145Snate@binkert.org
1597048Snate@binkert.org    m_periodic_output_file_ptr = new ofstream(filename.c_str());
1607048Snate@binkert.org    g_eventQueue_ptr->scheduleEvent(this, 1);
1617048Snate@binkert.org}
1627048Snate@binkert.org
1637048Snate@binkert.orgvoid
1647048Snate@binkert.orgProfiler::setPeriodicStatsInterval(integer_t period)
1657048Snate@binkert.org{
1667054Snate@binkert.org    cout << "Recording periodic statistics every " << m_stats_period
1677048Snate@binkert.org         << " Ruby cycles" << endl;
1687048Snate@binkert.org
1697048Snate@binkert.org    m_stats_period = period;
1707048Snate@binkert.org    g_eventQueue_ptr->scheduleEvent(this, 1);
1717048Snate@binkert.org}
1727048Snate@binkert.org
1737048Snate@binkert.orgvoid
1747048Snate@binkert.orgProfiler::printConfig(ostream& out) const
1757048Snate@binkert.org{
1767048Snate@binkert.org    out << endl;
1777048Snate@binkert.org    out << "Profiler Configuration" << endl;
1787048Snate@binkert.org    out << "----------------------" << endl;
1797048Snate@binkert.org    out << "periodic_stats_period: " << m_stats_period << endl;
1807048Snate@binkert.org}
1817048Snate@binkert.org
1827048Snate@binkert.orgvoid
1837048Snate@binkert.orgProfiler::print(ostream& out) const
1847048Snate@binkert.org{
1857048Snate@binkert.org    out << "[Profiler]";
1867048Snate@binkert.org}
1877048Snate@binkert.org
1887048Snate@binkert.orgvoid
1897048Snate@binkert.orgProfiler::printStats(ostream& out, bool short_stats)
1907048Snate@binkert.org{
1917048Snate@binkert.org    out << endl;
1927048Snate@binkert.org    if (short_stats) {
1937048Snate@binkert.org        out << "SHORT ";
1947048Snate@binkert.org    }
1957048Snate@binkert.org    out << "Profiler Stats" << endl;
1967048Snate@binkert.org    out << "--------------" << endl;
1977048Snate@binkert.org
1987048Snate@binkert.org    time_t real_time_current = time(NULL);
1997048Snate@binkert.org    double seconds = difftime(real_time_current, m_real_time_start_time);
2007048Snate@binkert.org    double minutes = seconds / 60.0;
2017048Snate@binkert.org    double hours = minutes / 60.0;
2027048Snate@binkert.org    double days = hours / 24.0;
2037048Snate@binkert.org    Time ruby_cycles = g_eventQueue_ptr->getTime()-m_ruby_start;
2047048Snate@binkert.org
2057048Snate@binkert.org    if (!short_stats) {
2067048Snate@binkert.org        out << "Elapsed_time_in_seconds: " << seconds << endl;
2077048Snate@binkert.org        out << "Elapsed_time_in_minutes: " << minutes << endl;
2087048Snate@binkert.org        out << "Elapsed_time_in_hours: " << hours << endl;
2097048Snate@binkert.org        out << "Elapsed_time_in_days: " << days << endl;
2107048Snate@binkert.org        out << endl;
2117048Snate@binkert.org    }
2127048Snate@binkert.org
2137048Snate@binkert.org    // print the virtual runtimes as well
2147048Snate@binkert.org    struct tms vtime;
2157048Snate@binkert.org    times(&vtime);
2167048Snate@binkert.org    seconds = (vtime.tms_utime + vtime.tms_stime) / 100.0;
2177048Snate@binkert.org    minutes = seconds / 60.0;
2187048Snate@binkert.org    hours = minutes / 60.0;
2197048Snate@binkert.org    days = hours / 24.0;
2207048Snate@binkert.org    out << "Virtual_time_in_seconds: " << seconds << endl;
2217048Snate@binkert.org    out << "Virtual_time_in_minutes: " << minutes << endl;
2227048Snate@binkert.org    out << "Virtual_time_in_hours:   " << hours << endl;
2237048Snate@binkert.org    out << "Virtual_time_in_days:    " << days << endl;
2246145Snate@binkert.org    out << endl;
2256145Snate@binkert.org
2267048Snate@binkert.org    out << "Ruby_current_time: " << g_eventQueue_ptr->getTime() << endl;
2277048Snate@binkert.org    out << "Ruby_start_time: " << m_ruby_start << endl;
2287048Snate@binkert.org    out << "Ruby_cycles: " << ruby_cycles << endl;
2296145Snate@binkert.org    out << endl;
2306145Snate@binkert.org
2317048Snate@binkert.org    if (!short_stats) {
2327048Snate@binkert.org        out << "mbytes_resident: " << process_memory_resident() << endl;
2337048Snate@binkert.org        out << "mbytes_total: " << process_memory_total() << endl;
2347048Snate@binkert.org        if (process_memory_total() > 0) {
2357054Snate@binkert.org            out << "resident_ratio: "
2367048Snate@binkert.org                << process_memory_resident()/process_memory_total() << endl;
2377048Snate@binkert.org        }
2387048Snate@binkert.org        out << endl;
2396145Snate@binkert.org    }
2406145Snate@binkert.org
2417454Snate@binkert.org    vector<integer_t> perProcCycleCount(m_num_of_sequencers);
2427048Snate@binkert.org
2437048Snate@binkert.org    for (int i = 0; i < m_num_of_sequencers; i++) {
2447048Snate@binkert.org        perProcCycleCount[i] =
2457048Snate@binkert.org            g_system_ptr->getCycleCount(i) - m_cycles_executed_at_start[i] + 1;
2467048Snate@binkert.org        // The +1 allows us to avoid division by zero
2476145Snate@binkert.org    }
2486145Snate@binkert.org
2497048Snate@binkert.org    out << "ruby_cycles_executed: " << perProcCycleCount << endl;
2507048Snate@binkert.org
2516145Snate@binkert.org    out << endl;
2527048Snate@binkert.org
2537048Snate@binkert.org    if (!short_stats) {
2547048Snate@binkert.org        out << "Busy Controller Counts:" << endl;
2557048Snate@binkert.org        for (int i = 0; i < MachineType_NUM; i++) {
2567048Snate@binkert.org            int size = MachineType_base_count((MachineType)i);
2577048Snate@binkert.org            for (int j = 0; j < size; j++) {
2587048Snate@binkert.org                MachineID machID;
2597048Snate@binkert.org                machID.type = (MachineType)i;
2607048Snate@binkert.org                machID.num = j;
2617048Snate@binkert.org                out << machID << ":" << m_busyControllerCount[i][j] << "  ";
2627048Snate@binkert.org                if ((j + 1) % 8 == 0) {
2637048Snate@binkert.org                    out << endl;
2647048Snate@binkert.org                }
2657048Snate@binkert.org            }
2667048Snate@binkert.org            out << endl;
2677048Snate@binkert.org        }
2687048Snate@binkert.org        out << endl;
2697048Snate@binkert.org
2707048Snate@binkert.org        out << "Busy Bank Count:" << m_busyBankCount << endl;
2717048Snate@binkert.org        out << endl;
2727048Snate@binkert.org
2737048Snate@binkert.org        out << "sequencer_requests_outstanding: "
2747048Snate@binkert.org            << m_sequencer_requests << endl;
2757048Snate@binkert.org        out << endl;
2766145Snate@binkert.org    }
2776145Snate@binkert.org
2787048Snate@binkert.org    if (!short_stats) {
2797048Snate@binkert.org        out << "All Non-Zero Cycle Demand Cache Accesses" << endl;
2807048Snate@binkert.org        out << "----------------------------------------" << endl;
2817048Snate@binkert.org        out << "miss_latency: " << m_allMissLatencyHistogram << endl;
2827048Snate@binkert.org        for (int i = 0; i < m_missLatencyHistograms.size(); i++) {
2837048Snate@binkert.org            if (m_missLatencyHistograms[i].size() > 0) {
2847048Snate@binkert.org                out << "miss_latency_" << RubyRequestType(i) << ": "
2857048Snate@binkert.org                    << m_missLatencyHistograms[i] << endl;
2867048Snate@binkert.org            }
2877048Snate@binkert.org        }
2887048Snate@binkert.org        for (int i = 0; i < m_machLatencyHistograms.size(); i++) {
2897048Snate@binkert.org            if (m_machLatencyHistograms[i].size() > 0) {
2907048Snate@binkert.org                out << "miss_latency_" << GenericMachineType(i) << ": "
2917048Snate@binkert.org                    << m_machLatencyHistograms[i] << endl;
2927048Snate@binkert.org            }
2937048Snate@binkert.org        }
2946145Snate@binkert.org
2957048Snate@binkert.org        out << endl;
2967048Snate@binkert.org
2977048Snate@binkert.org        out << "All Non-Zero Cycle SW Prefetch Requests" << endl;
2987048Snate@binkert.org        out << "------------------------------------" << endl;
2997048Snate@binkert.org        out << "prefetch_latency: " << m_allSWPrefetchLatencyHistogram << endl;
3007048Snate@binkert.org        for (int i = 0; i < m_SWPrefetchLatencyHistograms.size(); i++) {
3017048Snate@binkert.org            if (m_SWPrefetchLatencyHistograms[i].size() > 0) {
3027048Snate@binkert.org                out << "prefetch_latency_" << CacheRequestType(i) << ": "
3037048Snate@binkert.org                    << m_SWPrefetchLatencyHistograms[i] << endl;
3047048Snate@binkert.org            }
3057048Snate@binkert.org        }
3067048Snate@binkert.org        for (int i = 0; i < m_SWPrefetchMachLatencyHistograms.size(); i++) {
3077048Snate@binkert.org            if (m_SWPrefetchMachLatencyHistograms[i].size() > 0) {
3087048Snate@binkert.org                out << "prefetch_latency_" << GenericMachineType(i) << ": "
3097048Snate@binkert.org                    << m_SWPrefetchMachLatencyHistograms[i] << endl;
3107048Snate@binkert.org            }
3117048Snate@binkert.org        }
3127048Snate@binkert.org        out << "prefetch_latency_L2Miss:"
3137048Snate@binkert.org            << m_SWPrefetchL2MissLatencyHistogram << endl;
3147048Snate@binkert.org
3157048Snate@binkert.org        if (m_all_sharing_histogram.size() > 0) {
3167048Snate@binkert.org            out << "all_sharing: " << m_all_sharing_histogram << endl;
3177048Snate@binkert.org            out << "read_sharing: " << m_read_sharing_histogram << endl;
3187048Snate@binkert.org            out << "write_sharing: " << m_write_sharing_histogram << endl;
3197048Snate@binkert.org
3207048Snate@binkert.org            out << "all_sharing_percent: ";
3217048Snate@binkert.org            m_all_sharing_histogram.printPercent(out);
3227048Snate@binkert.org            out << endl;
3237048Snate@binkert.org
3247048Snate@binkert.org            out << "read_sharing_percent: ";
3257048Snate@binkert.org            m_read_sharing_histogram.printPercent(out);
3267048Snate@binkert.org            out << endl;
3277048Snate@binkert.org
3287048Snate@binkert.org            out << "write_sharing_percent: ";
3297048Snate@binkert.org            m_write_sharing_histogram.printPercent(out);
3307048Snate@binkert.org            out << endl;
3317048Snate@binkert.org
3327048Snate@binkert.org            int64 total_miss = m_cache_to_cache +  m_memory_to_cache;
3337048Snate@binkert.org            out << "all_misses: " << total_miss << endl;
3347048Snate@binkert.org            out << "cache_to_cache_misses: " << m_cache_to_cache << endl;
3357048Snate@binkert.org            out << "memory_to_cache_misses: " << m_memory_to_cache << endl;
3367048Snate@binkert.org            out << "cache_to_cache_percent: "
3377048Snate@binkert.org                << 100.0 * (double(m_cache_to_cache) / double(total_miss))
3387048Snate@binkert.org                << endl;
3397048Snate@binkert.org            out << "memory_to_cache_percent: "
3407048Snate@binkert.org                << 100.0 * (double(m_memory_to_cache) / double(total_miss))
3417048Snate@binkert.org                << endl;
3427048Snate@binkert.org            out << endl;
3437048Snate@binkert.org        }
3447048Snate@binkert.org
3457048Snate@binkert.org        if (m_outstanding_requests.size() > 0) {
3467048Snate@binkert.org            out << "outstanding_requests: ";
3477048Snate@binkert.org            m_outstanding_requests.printPercent(out);
3487048Snate@binkert.org            out << endl;
3497048Snate@binkert.org            out << endl;
3507048Snate@binkert.org        }
3517048Snate@binkert.org    }
3527048Snate@binkert.org
3537048Snate@binkert.org    if (!short_stats) {
3547048Snate@binkert.org        out << "Request vs. RubySystem State Profile" << endl;
3557048Snate@binkert.org        out << "--------------------------------" << endl;
3567048Snate@binkert.org        out << endl;
3577048Snate@binkert.org
3587454Snate@binkert.org        vector<string> requestProfileKeys = m_requestProfileMap_ptr->keys();
3597454Snate@binkert.org        sort(requestProfileKeys.begin(), requestProfileKeys.end());
3607048Snate@binkert.org
3617048Snate@binkert.org        for (int i = 0; i < requestProfileKeys.size(); i++) {
3627048Snate@binkert.org            int temp_int =
3637048Snate@binkert.org                m_requestProfileMap_ptr->lookup(requestProfileKeys[i]);
3647048Snate@binkert.org            double percent = (100.0 * double(temp_int)) / double(m_requests);
3657056Snate@binkert.org            vector<string> items;
3667056Snate@binkert.org            tokenize(items, requestProfileKeys[i], ':');
3677056Snate@binkert.org            vector<string>::iterator i = items.begin();
3687056Snate@binkert.org            vector<string>::iterator end = items.end();
3697056Snate@binkert.org            for (; i != end; ++i)
3707056Snate@binkert.org                out << setw(10) << *i;
3717048Snate@binkert.org            out << setw(11) << temp_int;
3727048Snate@binkert.org            out << setw(14) << percent << endl;
3737048Snate@binkert.org        }
3747048Snate@binkert.org        out << endl;
3757048Snate@binkert.org
3767048Snate@binkert.org        out << "filter_action: " << m_filter_action_histogram << endl;
3777048Snate@binkert.org
3787048Snate@binkert.org        if (!m_all_instructions) {
3797048Snate@binkert.org            m_address_profiler_ptr->printStats(out);
3807048Snate@binkert.org        }
3817048Snate@binkert.org
3827048Snate@binkert.org        if (m_all_instructions) {
3837048Snate@binkert.org            m_inst_profiler_ptr->printStats(out);
3847048Snate@binkert.org        }
3857048Snate@binkert.org
3867048Snate@binkert.org        out << endl;
3877048Snate@binkert.org        out << "Message Delayed Cycles" << endl;
3887048Snate@binkert.org        out << "----------------------" << endl;
3897048Snate@binkert.org        out << "Total_delay_cycles: " <<   m_delayedCyclesHistogram << endl;
3907048Snate@binkert.org        out << "Total_nonPF_delay_cycles: "
3917048Snate@binkert.org            << m_delayedCyclesNonPFHistogram << endl;
3927048Snate@binkert.org        for (int i = 0; i < m_delayedCyclesVCHistograms.size(); i++) {
3937048Snate@binkert.org            out << "  virtual_network_" << i << "_delay_cycles: "
3947048Snate@binkert.org                << m_delayedCyclesVCHistograms[i] << endl;
3957048Snate@binkert.org        }
3967048Snate@binkert.org
3977048Snate@binkert.org        printResourceUsage(out);
3987048Snate@binkert.org    }
3996145Snate@binkert.org}
4006145Snate@binkert.org
4017048Snate@binkert.orgvoid
4027048Snate@binkert.orgProfiler::printResourceUsage(ostream& out) const
4036145Snate@binkert.org{
4047048Snate@binkert.org    out << endl;
4057048Snate@binkert.org    out << "Resource Usage" << endl;
4067048Snate@binkert.org    out << "--------------" << endl;
4076145Snate@binkert.org
4087048Snate@binkert.org    integer_t pagesize = getpagesize(); // page size in bytes
4097048Snate@binkert.org    out << "page_size: " << pagesize << endl;
4106145Snate@binkert.org
4117048Snate@binkert.org    rusage usage;
4127048Snate@binkert.org    getrusage (RUSAGE_SELF, &usage);
4136145Snate@binkert.org
4147048Snate@binkert.org    out << "user_time: " << usage.ru_utime.tv_sec << endl;
4157048Snate@binkert.org    out << "system_time: " << usage.ru_stime.tv_sec << endl;
4167048Snate@binkert.org    out << "page_reclaims: " << usage.ru_minflt << endl;
4177048Snate@binkert.org    out << "page_faults: " << usage.ru_majflt << endl;
4187048Snate@binkert.org    out << "swaps: " << usage.ru_nswap << endl;
4197048Snate@binkert.org    out << "block_inputs: " << usage.ru_inblock << endl;
4207048Snate@binkert.org    out << "block_outputs: " << usage.ru_oublock << endl;
4216145Snate@binkert.org}
4226145Snate@binkert.org
4237048Snate@binkert.orgvoid
4247048Snate@binkert.orgProfiler::clearStats()
4256145Snate@binkert.org{
4267048Snate@binkert.org    m_ruby_start = g_eventQueue_ptr->getTime();
4276145Snate@binkert.org
4287454Snate@binkert.org    m_cycles_executed_at_start.resize(m_num_of_sequencers);
4297048Snate@binkert.org    for (int i = 0; i < m_num_of_sequencers; i++) {
4307048Snate@binkert.org        if (g_system_ptr == NULL) {
4317048Snate@binkert.org            m_cycles_executed_at_start[i] = 0;
4327048Snate@binkert.org        } else {
4337048Snate@binkert.org            m_cycles_executed_at_start[i] = g_system_ptr->getCycleCount(i);
4347048Snate@binkert.org        }
4356145Snate@binkert.org    }
4366145Snate@binkert.org
4377454Snate@binkert.org    m_busyControllerCount.resize(MachineType_NUM); // all machines
4387048Snate@binkert.org    for (int i = 0; i < MachineType_NUM; i++) {
4397048Snate@binkert.org        int size = MachineType_base_count((MachineType)i);
4407454Snate@binkert.org        m_busyControllerCount[i].resize(size);
4417048Snate@binkert.org        for (int j = 0; j < size; j++) {
4427048Snate@binkert.org            m_busyControllerCount[i][j] = 0;
4437048Snate@binkert.org        }
4446145Snate@binkert.org    }
4457048Snate@binkert.org    m_busyBankCount = 0;
4466145Snate@binkert.org
4477048Snate@binkert.org    m_delayedCyclesHistogram.clear();
4487048Snate@binkert.org    m_delayedCyclesNonPFHistogram.clear();
4497048Snate@binkert.org    int size = RubySystem::getNetwork()->getNumberOfVirtualNetworks();
4507454Snate@binkert.org    m_delayedCyclesVCHistograms.resize(size);
4517048Snate@binkert.org    for (int i = 0; i < size; i++) {
4527048Snate@binkert.org        m_delayedCyclesVCHistograms[i].clear();
4537048Snate@binkert.org    }
4546145Snate@binkert.org
4557454Snate@binkert.org    m_missLatencyHistograms.resize(RubyRequestType_NUM);
4567048Snate@binkert.org    for (int i = 0; i < m_missLatencyHistograms.size(); i++) {
4577048Snate@binkert.org        m_missLatencyHistograms[i].clear(200);
4587048Snate@binkert.org    }
4597454Snate@binkert.org    m_machLatencyHistograms.resize(GenericMachineType_NUM+1);
4607048Snate@binkert.org    for (int i = 0; i < m_machLatencyHistograms.size(); i++) {
4617048Snate@binkert.org        m_machLatencyHistograms[i].clear(200);
4627048Snate@binkert.org    }
4637048Snate@binkert.org    m_allMissLatencyHistogram.clear(200);
4646145Snate@binkert.org
4657454Snate@binkert.org    m_SWPrefetchLatencyHistograms.resize(CacheRequestType_NUM);
4667048Snate@binkert.org    for (int i = 0; i < m_SWPrefetchLatencyHistograms.size(); i++) {
4677048Snate@binkert.org        m_SWPrefetchLatencyHistograms[i].clear(200);
4687048Snate@binkert.org    }
4697454Snate@binkert.org    m_SWPrefetchMachLatencyHistograms.resize(GenericMachineType_NUM+1);
4707048Snate@binkert.org    for (int i = 0; i < m_SWPrefetchMachLatencyHistograms.size(); i++) {
4717048Snate@binkert.org        m_SWPrefetchMachLatencyHistograms[i].clear(200);
4727048Snate@binkert.org    }
4737048Snate@binkert.org    m_allSWPrefetchLatencyHistogram.clear(200);
4746145Snate@binkert.org
4757048Snate@binkert.org    m_sequencer_requests.clear();
4767048Snate@binkert.org    m_read_sharing_histogram.clear();
4777048Snate@binkert.org    m_write_sharing_histogram.clear();
4787048Snate@binkert.org    m_all_sharing_histogram.clear();
4797048Snate@binkert.org    m_cache_to_cache = 0;
4807048Snate@binkert.org    m_memory_to_cache = 0;
4816145Snate@binkert.org
4827048Snate@binkert.org    // clear HashMaps
4837048Snate@binkert.org    m_requestProfileMap_ptr->clear();
4846145Snate@binkert.org
4857048Snate@binkert.org    // count requests profiled
4867048Snate@binkert.org    m_requests = 0;
4876145Snate@binkert.org
4887048Snate@binkert.org    m_outstanding_requests.clear();
4897048Snate@binkert.org    m_outstanding_persistent_requests.clear();
4906145Snate@binkert.org
4917048Snate@binkert.org    // Flush the prefetches through the system - used so that there
4927048Snate@binkert.org    // are no outstanding requests after stats are cleared
4937048Snate@binkert.org    //g_eventQueue_ptr->triggerAllEvents();
4946145Snate@binkert.org
4957048Snate@binkert.org    // update the start time
4967048Snate@binkert.org    m_ruby_start = g_eventQueue_ptr->getTime();
4976145Snate@binkert.org}
4986145Snate@binkert.org
4997048Snate@binkert.orgvoid
5007048Snate@binkert.orgProfiler::addAddressTraceSample(const CacheMsg& msg, NodeID id)
5016145Snate@binkert.org{
5027048Snate@binkert.org    if (msg.getType() != CacheRequestType_IFETCH) {
5037048Snate@binkert.org        // Note: The following line should be commented out if you
5047048Snate@binkert.org        // want to use the special profiling that is part of the GS320
5057048Snate@binkert.org        // protocol
5066145Snate@binkert.org
5077048Snate@binkert.org        // NOTE: Unless PROFILE_HOT_LINES is enabled, nothing will be
5087048Snate@binkert.org        // profiled by the AddressProfiler
5097048Snate@binkert.org        m_address_profiler_ptr->
5107048Snate@binkert.org            addTraceSample(msg.getLineAddress(), msg.getProgramCounter(),
5117048Snate@binkert.org                           msg.getType(), msg.getAccessMode(), id, false);
5127048Snate@binkert.org    }
5136145Snate@binkert.org}
5146145Snate@binkert.org
5157048Snate@binkert.orgvoid
5167048Snate@binkert.orgProfiler::profileSharing(const Address& addr, AccessType type,
5177048Snate@binkert.org                         NodeID requestor, const Set& sharers,
5187048Snate@binkert.org                         const Set& owner)
5196145Snate@binkert.org{
5207048Snate@binkert.org    Set set_contacted(owner);
5217048Snate@binkert.org    if (type == AccessType_Write) {
5227048Snate@binkert.org        set_contacted.addSet(sharers);
5237048Snate@binkert.org    }
5247048Snate@binkert.org    set_contacted.remove(requestor);
5257048Snate@binkert.org    int number_contacted = set_contacted.count();
5266145Snate@binkert.org
5277048Snate@binkert.org    if (type == AccessType_Write) {
5287048Snate@binkert.org        m_write_sharing_histogram.add(number_contacted);
5297048Snate@binkert.org    } else {
5307048Snate@binkert.org        m_read_sharing_histogram.add(number_contacted);
5317048Snate@binkert.org    }
5327048Snate@binkert.org    m_all_sharing_histogram.add(number_contacted);
5336145Snate@binkert.org
5347048Snate@binkert.org    if (number_contacted == 0) {
5357048Snate@binkert.org        m_memory_to_cache++;
5367048Snate@binkert.org    } else {
5377048Snate@binkert.org        m_cache_to_cache++;
5387048Snate@binkert.org    }
5396145Snate@binkert.org}
5406145Snate@binkert.org
5417048Snate@binkert.orgvoid
5427048Snate@binkert.orgProfiler::profileMsgDelay(int virtualNetwork, int delayCycles)
5437048Snate@binkert.org{
5447048Snate@binkert.org    assert(virtualNetwork < m_delayedCyclesVCHistograms.size());
5457048Snate@binkert.org    m_delayedCyclesHistogram.add(delayCycles);
5467048Snate@binkert.org    m_delayedCyclesVCHistograms[virtualNetwork].add(delayCycles);
5477048Snate@binkert.org    if (virtualNetwork != 0) {
5487048Snate@binkert.org        m_delayedCyclesNonPFHistogram.add(delayCycles);
5497048Snate@binkert.org    }
5506145Snate@binkert.org}
5516145Snate@binkert.org
5526145Snate@binkert.org// profiles original cache requests including PUTs
5537048Snate@binkert.orgvoid
5547048Snate@binkert.orgProfiler::profileRequest(const string& requestStr)
5556145Snate@binkert.org{
5567048Snate@binkert.org    m_requests++;
5576145Snate@binkert.org
5587048Snate@binkert.org    if (m_requestProfileMap_ptr->exist(requestStr)) {
5597048Snate@binkert.org        (m_requestProfileMap_ptr->lookup(requestStr))++;
5607048Snate@binkert.org    } else {
5617048Snate@binkert.org        m_requestProfileMap_ptr->add(requestStr, 1);
5627048Snate@binkert.org    }
5636145Snate@binkert.org}
5646145Snate@binkert.org
5657048Snate@binkert.orgvoid
5667048Snate@binkert.orgProfiler::controllerBusy(MachineID machID)
5676145Snate@binkert.org{
5687048Snate@binkert.org    m_busyControllerCount[(int)machID.type][(int)machID.num]++;
5696145Snate@binkert.org}
5706145Snate@binkert.org
5717048Snate@binkert.orgvoid
5727048Snate@binkert.orgProfiler::profilePFWait(Time waitTime)
5736145Snate@binkert.org{
5747048Snate@binkert.org    m_prefetchWaitHistogram.add(waitTime);
5756145Snate@binkert.org}
5766145Snate@binkert.org
5777048Snate@binkert.orgvoid
5787048Snate@binkert.orgProfiler::bankBusy()
5796145Snate@binkert.org{
5807048Snate@binkert.org    m_busyBankCount++;
5816145Snate@binkert.org}
5826145Snate@binkert.org
5836145Snate@binkert.org// non-zero cycle demand request
5847048Snate@binkert.orgvoid
5857048Snate@binkert.orgProfiler::missLatency(Time t, RubyRequestType type)
5866145Snate@binkert.org{
5877048Snate@binkert.org    m_allMissLatencyHistogram.add(t);
5887048Snate@binkert.org    m_missLatencyHistograms[type].add(t);
5896145Snate@binkert.org}
5906145Snate@binkert.org
5916145Snate@binkert.org// non-zero cycle prefetch request
5927048Snate@binkert.orgvoid
5937048Snate@binkert.orgProfiler::swPrefetchLatency(Time t, CacheRequestType type,
5947048Snate@binkert.org                            GenericMachineType respondingMach)
5956145Snate@binkert.org{
5967048Snate@binkert.org    m_allSWPrefetchLatencyHistogram.add(t);
5977048Snate@binkert.org    m_SWPrefetchLatencyHistograms[type].add(t);
5987048Snate@binkert.org    m_SWPrefetchMachLatencyHistograms[respondingMach].add(t);
5997048Snate@binkert.org    if (respondingMach == GenericMachineType_Directory ||
6007048Snate@binkert.org        respondingMach == GenericMachineType_NUM) {
6017048Snate@binkert.org        m_SWPrefetchL2MissLatencyHistogram.add(t);
6027048Snate@binkert.org    }
6036145Snate@binkert.org}
6046145Snate@binkert.org
6057048Snate@binkert.orgvoid
6067048Snate@binkert.orgProfiler::profileTransition(const string& component, NodeID version,
6077048Snate@binkert.org    Address addr, const string& state, const string& event,
6087048Snate@binkert.org    const string& next_state, const string& note)
6096145Snate@binkert.org{
6107048Snate@binkert.org    const int EVENT_SPACES = 20;
6117048Snate@binkert.org    const int ID_SPACES = 3;
6127048Snate@binkert.org    const int TIME_SPACES = 7;
6137048Snate@binkert.org    const int COMP_SPACES = 10;
6147048Snate@binkert.org    const int STATE_SPACES = 6;
6156145Snate@binkert.org
6167048Snate@binkert.org    if (g_debug_ptr->getDebugTime() <= 0 ||
6177048Snate@binkert.org        g_eventQueue_ptr->getTime() < g_debug_ptr->getDebugTime())
6187048Snate@binkert.org        return;
6196145Snate@binkert.org
6207048Snate@binkert.org    ostream &out = *debug_cout_ptr;
6217048Snate@binkert.org    out.flags(ios::right);
6227048Snate@binkert.org    out << setw(TIME_SPACES) << g_eventQueue_ptr->getTime() << " ";
6237048Snate@binkert.org    out << setw(ID_SPACES) << version << " ";
6247048Snate@binkert.org    out << setw(COMP_SPACES) << component;
6257048Snate@binkert.org    out << setw(EVENT_SPACES) << event << " ";
6266285Snate@binkert.org
6277048Snate@binkert.org    out.flags(ios::right);
6287048Snate@binkert.org    out << setw(STATE_SPACES) << state;
6297048Snate@binkert.org    out << ">";
6307048Snate@binkert.org    out.flags(ios::left);
6317048Snate@binkert.org    out << setw(STATE_SPACES) << next_state;
6326145Snate@binkert.org
6337048Snate@binkert.org    out << " " << addr << " " << note;
6347048Snate@binkert.org
6357048Snate@binkert.org    out << endl;
6366145Snate@binkert.org}
6376145Snate@binkert.org
6386145Snate@binkert.org// Helper function
6397048Snate@binkert.orgstatic double
6407048Snate@binkert.orgprocess_memory_total()
6416145Snate@binkert.org{
6427048Snate@binkert.org    // 4kB page size, 1024*1024 bytes per MB,
6437054Snate@binkert.org    const double MULTIPLIER = 4096.0 / (1024.0 * 1024.0);
6447048Snate@binkert.org    ifstream proc_file;
6457048Snate@binkert.org    proc_file.open("/proc/self/statm");
6467048Snate@binkert.org    int total_size_in_pages = 0;
6477048Snate@binkert.org    int res_size_in_pages = 0;
6487048Snate@binkert.org    proc_file >> total_size_in_pages;
6497048Snate@binkert.org    proc_file >> res_size_in_pages;
6507048Snate@binkert.org    return double(total_size_in_pages) * MULTIPLIER; // size in megabytes
6516145Snate@binkert.org}
6526145Snate@binkert.org
6537048Snate@binkert.orgstatic double
6547048Snate@binkert.orgprocess_memory_resident()
6556145Snate@binkert.org{
6567048Snate@binkert.org    // 4kB page size, 1024*1024 bytes per MB,
6577048Snate@binkert.org    const double MULTIPLIER = 4096.0 / (1024.0 * 1024.0);
6587048Snate@binkert.org    ifstream proc_file;
6597048Snate@binkert.org    proc_file.open("/proc/self/statm");
6607048Snate@binkert.org    int total_size_in_pages = 0;
6617048Snate@binkert.org    int res_size_in_pages = 0;
6627048Snate@binkert.org    proc_file >> total_size_in_pages;
6637048Snate@binkert.org    proc_file >> res_size_in_pages;
6647048Snate@binkert.org    return double(res_size_in_pages) * MULTIPLIER; // size in megabytes
6656145Snate@binkert.org}
6666145Snate@binkert.org
6677048Snate@binkert.orgvoid
6687048Snate@binkert.orgProfiler::rubyWatch(int id)
6697048Snate@binkert.org{
6707010SBrad.Beckmann@amd.com    uint64 tr = 0;
6716285Snate@binkert.org    Address watch_address = Address(tr);
6726285Snate@binkert.org    const int ID_SPACES = 3;
6736285Snate@binkert.org    const int TIME_SPACES = 7;
6746285Snate@binkert.org
6757048Snate@binkert.org    ostream &out = *debug_cout_ptr;
6766285Snate@binkert.org
6777048Snate@binkert.org    out.flags(ios::right);
6787048Snate@binkert.org    out << setw(TIME_SPACES) << g_eventQueue_ptr->getTime() << " ";
6797048Snate@binkert.org    out << setw(ID_SPACES) << id << " "
6807048Snate@binkert.org        << "RUBY WATCH " << watch_address << endl;
6817048Snate@binkert.org
6827048Snate@binkert.org    if (!m_watch_address_list_ptr->exist(watch_address)) {
6837048Snate@binkert.org        m_watch_address_list_ptr->add(watch_address, 1);
6846285Snate@binkert.org    }
6856285Snate@binkert.org}
6866285Snate@binkert.org
6877048Snate@binkert.orgbool
6887048Snate@binkert.orgProfiler::watchAddress(Address addr)
6897048Snate@binkert.org{
6906285Snate@binkert.org    if (m_watch_address_list_ptr->exist(addr))
6917048Snate@binkert.org        return true;
6926285Snate@binkert.org    else
6937048Snate@binkert.org        return false;
6946285Snate@binkert.org}
6956285Snate@binkert.org
6966876Ssteve.reinhardt@amd.comProfiler *
6976876Ssteve.reinhardt@amd.comRubyProfilerParams::create()
6986876Ssteve.reinhardt@amd.com{
6996876Ssteve.reinhardt@amd.com    return new Profiler(this);
7006876Ssteve.reinhardt@amd.com}
701