AddressProfiler.cc revision 7055
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
297048Snate@binkert.org#include "mem/gems_common/Map.hh"
307048Snate@binkert.org#include "mem/gems_common/PrioHeap.hh"
316154Snate@binkert.org#include "mem/protocol/CacheMsg.hh"
326154Snate@binkert.org#include "mem/ruby/profiler/AccessTraceForAddress.hh"
337048Snate@binkert.org#include "mem/ruby/profiler/AddressProfiler.hh"
347048Snate@binkert.org#include "mem/ruby/profiler/Profiler.hh"
356154Snate@binkert.org#include "mem/ruby/system/System.hh"
367048Snate@binkert.org
377055Snate@binkert.orgusing namespace std;
387048Snate@binkert.orgtypedef AddressProfiler::AddressMap AddressMap;
396145Snate@binkert.org
406145Snate@binkert.org// Helper functions
417048Snate@binkert.orgAccessTraceForAddress&
427048Snate@binkert.orglookupTraceForAddress(const Address& addr, AddressMap* record_map)
437048Snate@binkert.org{
447048Snate@binkert.org    if (!record_map->exist(addr)) {
457048Snate@binkert.org        record_map->add(addr, AccessTraceForAddress(addr));
467048Snate@binkert.org    }
477048Snate@binkert.org    return record_map->lookup(addr);
487048Snate@binkert.org}
496145Snate@binkert.org
507048Snate@binkert.orgvoid
517054Snate@binkert.orgprintSorted(ostream& out, int num_of_sequencers, const AddressMap* record_map,
527048Snate@binkert.org            string description)
537048Snate@binkert.org{
547048Snate@binkert.org    const int records_printed = 100;
557048Snate@binkert.org
567048Snate@binkert.org    uint64 misses = 0;
577048Snate@binkert.org    PrioHeap<AccessTraceForAddress*> heap;
587048Snate@binkert.org    Vector<Address> keys = record_map->keys();
597048Snate@binkert.org    for (int i = 0; i < keys.size(); i++) {
607048Snate@binkert.org        AccessTraceForAddress* record = &(record_map->lookup(keys[i]));
617048Snate@binkert.org        misses += record->getTotal();
627048Snate@binkert.org        heap.insert(record);
637048Snate@binkert.org    }
647048Snate@binkert.org
657048Snate@binkert.org    out << "Total_entries_" << description << ": " << keys.size() << endl;
667048Snate@binkert.org    if (g_system_ptr->getProfiler()->getAllInstructions())
677048Snate@binkert.org        out << "Total_Instructions_" << description << ": " << misses << endl;
687048Snate@binkert.org    else
697048Snate@binkert.org        out << "Total_data_misses_" << description << ": " << misses << endl;
707048Snate@binkert.org
717048Snate@binkert.org    out << "total | load store atomic | user supervisor | sharing | touched-by"
727048Snate@binkert.org        << endl;
737048Snate@binkert.org
747048Snate@binkert.org    Histogram remaining_records(1, 100);
757048Snate@binkert.org    Histogram all_records(1, 100);
767048Snate@binkert.org    Histogram remaining_records_log(-1);
777048Snate@binkert.org    Histogram all_records_log(-1);
787048Snate@binkert.org
797048Snate@binkert.org    // Allows us to track how many lines where touched by n processors
807048Snate@binkert.org    Vector<int64> m_touched_vec;
817048Snate@binkert.org    Vector<int64> m_touched_weighted_vec;
827048Snate@binkert.org    m_touched_vec.setSize(num_of_sequencers+1);
837048Snate@binkert.org    m_touched_weighted_vec.setSize(num_of_sequencers+1);
847048Snate@binkert.org    for (int i = 0; i < m_touched_vec.size(); i++) {
857048Snate@binkert.org        m_touched_vec[i] = 0;
867048Snate@binkert.org        m_touched_weighted_vec[i] = 0;
877048Snate@binkert.org    }
887048Snate@binkert.org
897048Snate@binkert.org    int counter = 0;
907048Snate@binkert.org    while (heap.size() > 0 && counter < records_printed) {
917048Snate@binkert.org        AccessTraceForAddress* record = heap.extractMin();
927048Snate@binkert.org        double percent = 100.0 * (record->getTotal() / double(misses));
937048Snate@binkert.org        out << description << " | " << percent << " % " << *record << endl;
947048Snate@binkert.org        all_records.add(record->getTotal());
957048Snate@binkert.org        all_records_log.add(record->getTotal());
967048Snate@binkert.org        counter++;
977048Snate@binkert.org        m_touched_vec[record->getTouchedBy()]++;
987048Snate@binkert.org        m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
997048Snate@binkert.org    }
1007048Snate@binkert.org
1017048Snate@binkert.org    while (heap.size() > 0) {
1027048Snate@binkert.org        AccessTraceForAddress* record = heap.extractMin();
1037048Snate@binkert.org        all_records.add(record->getTotal());
1047048Snate@binkert.org        remaining_records.add(record->getTotal());
1057048Snate@binkert.org        all_records_log.add(record->getTotal());
1067048Snate@binkert.org        remaining_records_log.add(record->getTotal());
1077048Snate@binkert.org        m_touched_vec[record->getTouchedBy()]++;
1087048Snate@binkert.org        m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
1097048Snate@binkert.org    }
1107048Snate@binkert.org    out << endl;
1117048Snate@binkert.org    out << "all_records_" << description << ": "
1127048Snate@binkert.org        << all_records << endl
1137048Snate@binkert.org        << "all_records_log_" << description << ": "
1147048Snate@binkert.org        << all_records_log << endl
1157048Snate@binkert.org        << "remaining_records_" << description << ": "
1167048Snate@binkert.org        << remaining_records << endl
1177048Snate@binkert.org        << "remaining_records_log_" << description << ": "
1187048Snate@binkert.org        << remaining_records_log << endl
1197048Snate@binkert.org        << "touched_by_" << description << ": "
1207048Snate@binkert.org        << m_touched_vec << endl
1217048Snate@binkert.org        << "touched_by_weighted_" << description << ": "
1227048Snate@binkert.org        << m_touched_weighted_vec << endl
1237048Snate@binkert.org        << endl;
1247048Snate@binkert.org}
1256896SBrad.Beckmann@amd.com
1266896SBrad.Beckmann@amd.comAddressProfiler::AddressProfiler(int num_of_sequencers)
1276145Snate@binkert.org{
1287048Snate@binkert.org    m_dataAccessTrace = new AddressMap;
1297048Snate@binkert.org    m_macroBlockAccessTrace = new AddressMap;
1307048Snate@binkert.org    m_programCounterAccessTrace = new AddressMap;
1317048Snate@binkert.org    m_retryProfileMap = new AddressMap;
1327048Snate@binkert.org    m_num_of_sequencers = num_of_sequencers;
1337048Snate@binkert.org    clearStats();
1346145Snate@binkert.org}
1356145Snate@binkert.org
1366145Snate@binkert.orgAddressProfiler::~AddressProfiler()
1376145Snate@binkert.org{
1387048Snate@binkert.org    delete m_dataAccessTrace;
1397048Snate@binkert.org    delete m_macroBlockAccessTrace;
1407048Snate@binkert.org    delete m_programCounterAccessTrace;
1417048Snate@binkert.org    delete m_retryProfileMap;
1426145Snate@binkert.org}
1436145Snate@binkert.org
1447048Snate@binkert.orgvoid
1457048Snate@binkert.orgAddressProfiler::setHotLines(bool hot_lines)
1467048Snate@binkert.org{
1477048Snate@binkert.org    m_hot_lines = hot_lines;
1486285Snate@binkert.org}
1496285Snate@binkert.org
1507048Snate@binkert.orgvoid
1517048Snate@binkert.orgAddressProfiler::setAllInstructions(bool all_instructions)
1526145Snate@binkert.org{
1537048Snate@binkert.org    m_all_instructions = all_instructions;
1546145Snate@binkert.org}
1556145Snate@binkert.org
1567048Snate@binkert.orgvoid
1577048Snate@binkert.orgAddressProfiler::printStats(ostream& out) const
1586145Snate@binkert.org{
1597048Snate@binkert.org    if (m_hot_lines) {
1607048Snate@binkert.org        out << endl;
1617048Snate@binkert.org        out << "AddressProfiler Stats" << endl;
1627048Snate@binkert.org        out << "---------------------" << endl;
1637048Snate@binkert.org
1647048Snate@binkert.org        out << endl;
1657048Snate@binkert.org        out << "sharing_misses: " << m_sharing_miss_counter << endl;
1667048Snate@binkert.org        out << "getx_sharing_histogram: " << m_getx_sharing_histogram << endl;
1677048Snate@binkert.org        out << "gets_sharing_histogram: " << m_gets_sharing_histogram << endl;
1687048Snate@binkert.org
1697048Snate@binkert.org        out << endl;
1707048Snate@binkert.org        out << "Hot Data Blocks" << endl;
1717048Snate@binkert.org        out << "---------------" << endl;
1727048Snate@binkert.org        out << endl;
1737048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_dataAccessTrace,
1747048Snate@binkert.org                    "block_address");
1757048Snate@binkert.org
1767048Snate@binkert.org        out << endl;
1777048Snate@binkert.org        out << "Hot MacroData Blocks" << endl;
1787048Snate@binkert.org        out << "--------------------" << endl;
1797048Snate@binkert.org        out << endl;
1807048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_macroBlockAccessTrace,
1817048Snate@binkert.org                    "macroblock_address");
1827048Snate@binkert.org
1837048Snate@binkert.org        out << "Hot Instructions" << endl;
1847048Snate@binkert.org        out << "----------------" << endl;
1857048Snate@binkert.org        out << endl;
1867048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
1877048Snate@binkert.org                    "pc_address");
1887048Snate@binkert.org    }
1897048Snate@binkert.org
1907048Snate@binkert.org    if (m_all_instructions) {
1917048Snate@binkert.org        out << endl;
1927048Snate@binkert.org        out << "All Instructions Profile:" << endl;
1937048Snate@binkert.org        out << "-------------------------" << endl;
1947048Snate@binkert.org        out << endl;
1957048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
1967048Snate@binkert.org                    "pc_address");
1977048Snate@binkert.org        out << endl;
1987048Snate@binkert.org    }
1997048Snate@binkert.org
2007048Snate@binkert.org    if (m_retryProfileHisto.size() > 0) {
2017048Snate@binkert.org        out << "Retry Profile" << endl;
2027048Snate@binkert.org        out << "-------------" << endl;
2037048Snate@binkert.org        out << endl;
2047048Snate@binkert.org        out << "retry_histogram_absolute: " << m_retryProfileHisto << endl;
2057048Snate@binkert.org        out << "retry_histogram_write: " << m_retryProfileHistoWrite << endl;
2067048Snate@binkert.org        out << "retry_histogram_read: " << m_retryProfileHistoRead << endl;
2077048Snate@binkert.org
2087048Snate@binkert.org        out << "retry_histogram_percent: ";
2097048Snate@binkert.org        m_retryProfileHisto.printPercent(out);
2107048Snate@binkert.org        out << endl;
2117048Snate@binkert.org
2127048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_retryProfileMap,
2137048Snate@binkert.org                    "block_address");
2147048Snate@binkert.org        out << endl;
2157048Snate@binkert.org    }
2166145Snate@binkert.org}
2176145Snate@binkert.org
2187048Snate@binkert.orgvoid
2197048Snate@binkert.orgAddressProfiler::clearStats()
2206145Snate@binkert.org{
2217048Snate@binkert.org    // Clear the maps
2227048Snate@binkert.org    m_sharing_miss_counter = 0;
2237048Snate@binkert.org    m_dataAccessTrace->clear();
2247048Snate@binkert.org    m_macroBlockAccessTrace->clear();
2257048Snate@binkert.org    m_programCounterAccessTrace->clear();
2267048Snate@binkert.org    m_retryProfileMap->clear();
2277048Snate@binkert.org    m_retryProfileHisto.clear();
2287048Snate@binkert.org    m_retryProfileHistoRead.clear();
2297048Snate@binkert.org    m_retryProfileHistoWrite.clear();
2307048Snate@binkert.org    m_getx_sharing_histogram.clear();
2317048Snate@binkert.org    m_gets_sharing_histogram.clear();
2326145Snate@binkert.org}
2336145Snate@binkert.org
2347048Snate@binkert.orgvoid
2357048Snate@binkert.orgAddressProfiler::profileGetX(const Address& datablock, const Address& PC,
2367048Snate@binkert.org                             const Set& owner, const Set& sharers,
2377048Snate@binkert.org                             NodeID requestor)
2386145Snate@binkert.org{
2397048Snate@binkert.org    Set indirection_set;
2407048Snate@binkert.org    indirection_set.addSet(sharers);
2417048Snate@binkert.org    indirection_set.addSet(owner);
2427048Snate@binkert.org    indirection_set.remove(requestor);
2437048Snate@binkert.org    int num_indirections = indirection_set.count();
2446145Snate@binkert.org
2457048Snate@binkert.org    m_getx_sharing_histogram.add(num_indirections);
2467048Snate@binkert.org    bool indirection_miss = (num_indirections > 0);
2476145Snate@binkert.org
2487048Snate@binkert.org    addTraceSample(datablock, PC, CacheRequestType_ST, AccessModeType(0),
2497048Snate@binkert.org                   requestor, indirection_miss);
2506145Snate@binkert.org}
2516145Snate@binkert.org
2527048Snate@binkert.orgvoid
2537048Snate@binkert.orgAddressProfiler::profileGetS(const Address& datablock, const Address& PC,
2547048Snate@binkert.org                             const Set& owner, const Set& sharers,
2557048Snate@binkert.org                             NodeID requestor)
2566145Snate@binkert.org{
2577048Snate@binkert.org    Set indirection_set;
2587048Snate@binkert.org    indirection_set.addSet(owner);
2597048Snate@binkert.org    indirection_set.remove(requestor);
2607048Snate@binkert.org    int num_indirections = indirection_set.count();
2617048Snate@binkert.org
2627048Snate@binkert.org    m_gets_sharing_histogram.add(num_indirections);
2637048Snate@binkert.org    bool indirection_miss = (num_indirections > 0);
2647048Snate@binkert.org
2657048Snate@binkert.org    addTraceSample(datablock, PC, CacheRequestType_LD, AccessModeType(0),
2667048Snate@binkert.org                   requestor, indirection_miss);
2677048Snate@binkert.org}
2687048Snate@binkert.org
2697048Snate@binkert.orgvoid
2707048Snate@binkert.orgAddressProfiler::addTraceSample(Address data_addr, Address pc_addr,
2717048Snate@binkert.org                                CacheRequestType type,
2727048Snate@binkert.org                                AccessModeType access_mode, NodeID id,
2737048Snate@binkert.org                                bool sharing_miss)
2747048Snate@binkert.org{
2757048Snate@binkert.org    if (m_all_instructions) {
2767048Snate@binkert.org        if (sharing_miss) {
2777048Snate@binkert.org            m_sharing_miss_counter++;
2787048Snate@binkert.org        }
2797048Snate@binkert.org
2807048Snate@binkert.org        // record data address trace info
2817048Snate@binkert.org        data_addr.makeLineAddress();
2827048Snate@binkert.org        lookupTraceForAddress(data_addr, m_dataAccessTrace).
2837048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
2847048Snate@binkert.org
2857048Snate@binkert.org        // record macro data address trace info
2867048Snate@binkert.org
2877048Snate@binkert.org        // 6 for datablock, 4 to make it 16x more coarse
2887048Snate@binkert.org        Address macro_addr(data_addr.maskLowOrderBits(10));
2897048Snate@binkert.org        lookupTraceForAddress(macro_addr, m_macroBlockAccessTrace).
2907048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
2917048Snate@binkert.org
2927048Snate@binkert.org        // record program counter address trace info
2937048Snate@binkert.org        lookupTraceForAddress(pc_addr, m_programCounterAccessTrace).
2947048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
2956145Snate@binkert.org    }
2966145Snate@binkert.org
2977048Snate@binkert.org    if (m_all_instructions) {
2987048Snate@binkert.org        // This code is used if the address profiler is an
2997048Snate@binkert.org        // all-instructions profiler record program counter address
3007048Snate@binkert.org        // trace info
3017048Snate@binkert.org        lookupTraceForAddress(pc_addr, m_programCounterAccessTrace).
3027048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
3037048Snate@binkert.org    }
3046145Snate@binkert.org}
3056145Snate@binkert.org
3067048Snate@binkert.orgvoid
3077048Snate@binkert.orgAddressProfiler::profileRetry(const Address& data_addr, AccessType type,
3087048Snate@binkert.org                              int count)
3096145Snate@binkert.org{
3107048Snate@binkert.org    m_retryProfileHisto.add(count);
3117048Snate@binkert.org    if (type == AccessType_Read) {
3127048Snate@binkert.org        m_retryProfileHistoRead.add(count);
3137048Snate@binkert.org    } else {
3147048Snate@binkert.org        m_retryProfileHistoWrite.add(count);
3157048Snate@binkert.org    }
3167048Snate@binkert.org    if (count > 1) {
3177048Snate@binkert.org        lookupTraceForAddress(data_addr, m_retryProfileMap).addSample(count);
3187048Snate@binkert.org    }
3196145Snate@binkert.org}
320