AddressProfiler.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
297454Snate@binkert.org#include <vector>
307454Snate@binkert.org
317454Snate@binkert.org#include "base/stl_helpers.hh"
327048Snate@binkert.org#include "mem/gems_common/Map.hh"
337048Snate@binkert.org#include "mem/gems_common/PrioHeap.hh"
346154Snate@binkert.org#include "mem/protocol/CacheMsg.hh"
356154Snate@binkert.org#include "mem/ruby/profiler/AccessTraceForAddress.hh"
367048Snate@binkert.org#include "mem/ruby/profiler/AddressProfiler.hh"
377048Snate@binkert.org#include "mem/ruby/profiler/Profiler.hh"
386154Snate@binkert.org#include "mem/ruby/system/System.hh"
397048Snate@binkert.org
407055Snate@binkert.orgusing namespace std;
417048Snate@binkert.orgtypedef AddressProfiler::AddressMap AddressMap;
426145Snate@binkert.org
437454Snate@binkert.orgusing m5::stl_helpers::operator<<;
447454Snate@binkert.org
456145Snate@binkert.org// Helper functions
467048Snate@binkert.orgAccessTraceForAddress&
477048Snate@binkert.orglookupTraceForAddress(const Address& addr, AddressMap* record_map)
487048Snate@binkert.org{
497048Snate@binkert.org    if (!record_map->exist(addr)) {
507048Snate@binkert.org        record_map->add(addr, AccessTraceForAddress(addr));
517048Snate@binkert.org    }
527048Snate@binkert.org    return record_map->lookup(addr);
537048Snate@binkert.org}
546145Snate@binkert.org
557048Snate@binkert.orgvoid
567054Snate@binkert.orgprintSorted(ostream& out, int num_of_sequencers, const AddressMap* record_map,
577048Snate@binkert.org            string description)
587048Snate@binkert.org{
597048Snate@binkert.org    const int records_printed = 100;
607048Snate@binkert.org
617048Snate@binkert.org    uint64 misses = 0;
627048Snate@binkert.org    PrioHeap<AccessTraceForAddress*> heap;
637454Snate@binkert.org    std::vector<Address> keys = record_map->keys();
647048Snate@binkert.org    for (int i = 0; i < keys.size(); i++) {
657048Snate@binkert.org        AccessTraceForAddress* record = &(record_map->lookup(keys[i]));
667048Snate@binkert.org        misses += record->getTotal();
677048Snate@binkert.org        heap.insert(record);
687048Snate@binkert.org    }
697048Snate@binkert.org
707048Snate@binkert.org    out << "Total_entries_" << description << ": " << keys.size() << endl;
717048Snate@binkert.org    if (g_system_ptr->getProfiler()->getAllInstructions())
727048Snate@binkert.org        out << "Total_Instructions_" << description << ": " << misses << endl;
737048Snate@binkert.org    else
747048Snate@binkert.org        out << "Total_data_misses_" << description << ": " << misses << endl;
757048Snate@binkert.org
767048Snate@binkert.org    out << "total | load store atomic | user supervisor | sharing | touched-by"
777048Snate@binkert.org        << endl;
787048Snate@binkert.org
797048Snate@binkert.org    Histogram remaining_records(1, 100);
807048Snate@binkert.org    Histogram all_records(1, 100);
817048Snate@binkert.org    Histogram remaining_records_log(-1);
827048Snate@binkert.org    Histogram all_records_log(-1);
837048Snate@binkert.org
847048Snate@binkert.org    // Allows us to track how many lines where touched by n processors
857454Snate@binkert.org    std::vector<int64> m_touched_vec;
867454Snate@binkert.org    std::vector<int64> m_touched_weighted_vec;
877454Snate@binkert.org    m_touched_vec.resize(num_of_sequencers+1);
887454Snate@binkert.org    m_touched_weighted_vec.resize(num_of_sequencers+1);
897048Snate@binkert.org    for (int i = 0; i < m_touched_vec.size(); i++) {
907048Snate@binkert.org        m_touched_vec[i] = 0;
917048Snate@binkert.org        m_touched_weighted_vec[i] = 0;
927048Snate@binkert.org    }
937048Snate@binkert.org
947048Snate@binkert.org    int counter = 0;
957048Snate@binkert.org    while (heap.size() > 0 && counter < records_printed) {
967048Snate@binkert.org        AccessTraceForAddress* record = heap.extractMin();
977048Snate@binkert.org        double percent = 100.0 * (record->getTotal() / double(misses));
987048Snate@binkert.org        out << description << " | " << percent << " % " << *record << endl;
997048Snate@binkert.org        all_records.add(record->getTotal());
1007048Snate@binkert.org        all_records_log.add(record->getTotal());
1017048Snate@binkert.org        counter++;
1027048Snate@binkert.org        m_touched_vec[record->getTouchedBy()]++;
1037048Snate@binkert.org        m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
1047048Snate@binkert.org    }
1057048Snate@binkert.org
1067048Snate@binkert.org    while (heap.size() > 0) {
1077048Snate@binkert.org        AccessTraceForAddress* record = heap.extractMin();
1087048Snate@binkert.org        all_records.add(record->getTotal());
1097048Snate@binkert.org        remaining_records.add(record->getTotal());
1107048Snate@binkert.org        all_records_log.add(record->getTotal());
1117048Snate@binkert.org        remaining_records_log.add(record->getTotal());
1127048Snate@binkert.org        m_touched_vec[record->getTouchedBy()]++;
1137048Snate@binkert.org        m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
1147048Snate@binkert.org    }
1157048Snate@binkert.org    out << endl;
1167048Snate@binkert.org    out << "all_records_" << description << ": "
1177048Snate@binkert.org        << all_records << endl
1187048Snate@binkert.org        << "all_records_log_" << description << ": "
1197048Snate@binkert.org        << all_records_log << endl
1207048Snate@binkert.org        << "remaining_records_" << description << ": "
1217048Snate@binkert.org        << remaining_records << endl
1227048Snate@binkert.org        << "remaining_records_log_" << description << ": "
1237048Snate@binkert.org        << remaining_records_log << endl
1247048Snate@binkert.org        << "touched_by_" << description << ": "
1257048Snate@binkert.org        << m_touched_vec << endl
1267048Snate@binkert.org        << "touched_by_weighted_" << description << ": "
1277048Snate@binkert.org        << m_touched_weighted_vec << endl
1287048Snate@binkert.org        << endl;
1297048Snate@binkert.org}
1306896SBrad.Beckmann@amd.com
1316896SBrad.Beckmann@amd.comAddressProfiler::AddressProfiler(int num_of_sequencers)
1326145Snate@binkert.org{
1337048Snate@binkert.org    m_dataAccessTrace = new AddressMap;
1347048Snate@binkert.org    m_macroBlockAccessTrace = new AddressMap;
1357048Snate@binkert.org    m_programCounterAccessTrace = new AddressMap;
1367048Snate@binkert.org    m_retryProfileMap = new AddressMap;
1377048Snate@binkert.org    m_num_of_sequencers = num_of_sequencers;
1387048Snate@binkert.org    clearStats();
1396145Snate@binkert.org}
1406145Snate@binkert.org
1416145Snate@binkert.orgAddressProfiler::~AddressProfiler()
1426145Snate@binkert.org{
1437048Snate@binkert.org    delete m_dataAccessTrace;
1447048Snate@binkert.org    delete m_macroBlockAccessTrace;
1457048Snate@binkert.org    delete m_programCounterAccessTrace;
1467048Snate@binkert.org    delete m_retryProfileMap;
1476145Snate@binkert.org}
1486145Snate@binkert.org
1497048Snate@binkert.orgvoid
1507048Snate@binkert.orgAddressProfiler::setHotLines(bool hot_lines)
1517048Snate@binkert.org{
1527048Snate@binkert.org    m_hot_lines = hot_lines;
1536285Snate@binkert.org}
1546285Snate@binkert.org
1557048Snate@binkert.orgvoid
1567048Snate@binkert.orgAddressProfiler::setAllInstructions(bool all_instructions)
1576145Snate@binkert.org{
1587048Snate@binkert.org    m_all_instructions = all_instructions;
1596145Snate@binkert.org}
1606145Snate@binkert.org
1617048Snate@binkert.orgvoid
1627048Snate@binkert.orgAddressProfiler::printStats(ostream& out) const
1636145Snate@binkert.org{
1647048Snate@binkert.org    if (m_hot_lines) {
1657048Snate@binkert.org        out << endl;
1667048Snate@binkert.org        out << "AddressProfiler Stats" << endl;
1677048Snate@binkert.org        out << "---------------------" << endl;
1687048Snate@binkert.org
1697048Snate@binkert.org        out << endl;
1707048Snate@binkert.org        out << "sharing_misses: " << m_sharing_miss_counter << endl;
1717048Snate@binkert.org        out << "getx_sharing_histogram: " << m_getx_sharing_histogram << endl;
1727048Snate@binkert.org        out << "gets_sharing_histogram: " << m_gets_sharing_histogram << endl;
1737048Snate@binkert.org
1747048Snate@binkert.org        out << endl;
1757048Snate@binkert.org        out << "Hot Data Blocks" << endl;
1767048Snate@binkert.org        out << "---------------" << endl;
1777048Snate@binkert.org        out << endl;
1787048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_dataAccessTrace,
1797048Snate@binkert.org                    "block_address");
1807048Snate@binkert.org
1817048Snate@binkert.org        out << endl;
1827048Snate@binkert.org        out << "Hot MacroData Blocks" << endl;
1837048Snate@binkert.org        out << "--------------------" << endl;
1847048Snate@binkert.org        out << endl;
1857048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_macroBlockAccessTrace,
1867048Snate@binkert.org                    "macroblock_address");
1877048Snate@binkert.org
1887048Snate@binkert.org        out << "Hot Instructions" << endl;
1897048Snate@binkert.org        out << "----------------" << endl;
1907048Snate@binkert.org        out << endl;
1917048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
1927048Snate@binkert.org                    "pc_address");
1937048Snate@binkert.org    }
1947048Snate@binkert.org
1957048Snate@binkert.org    if (m_all_instructions) {
1967048Snate@binkert.org        out << endl;
1977048Snate@binkert.org        out << "All Instructions Profile:" << endl;
1987048Snate@binkert.org        out << "-------------------------" << endl;
1997048Snate@binkert.org        out << endl;
2007048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
2017048Snate@binkert.org                    "pc_address");
2027048Snate@binkert.org        out << endl;
2037048Snate@binkert.org    }
2047048Snate@binkert.org
2057048Snate@binkert.org    if (m_retryProfileHisto.size() > 0) {
2067048Snate@binkert.org        out << "Retry Profile" << endl;
2077048Snate@binkert.org        out << "-------------" << endl;
2087048Snate@binkert.org        out << endl;
2097048Snate@binkert.org        out << "retry_histogram_absolute: " << m_retryProfileHisto << endl;
2107048Snate@binkert.org        out << "retry_histogram_write: " << m_retryProfileHistoWrite << endl;
2117048Snate@binkert.org        out << "retry_histogram_read: " << m_retryProfileHistoRead << endl;
2127048Snate@binkert.org
2137048Snate@binkert.org        out << "retry_histogram_percent: ";
2147048Snate@binkert.org        m_retryProfileHisto.printPercent(out);
2157048Snate@binkert.org        out << endl;
2167048Snate@binkert.org
2177048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_retryProfileMap,
2187048Snate@binkert.org                    "block_address");
2197048Snate@binkert.org        out << endl;
2207048Snate@binkert.org    }
2216145Snate@binkert.org}
2226145Snate@binkert.org
2237048Snate@binkert.orgvoid
2247048Snate@binkert.orgAddressProfiler::clearStats()
2256145Snate@binkert.org{
2267048Snate@binkert.org    // Clear the maps
2277048Snate@binkert.org    m_sharing_miss_counter = 0;
2287048Snate@binkert.org    m_dataAccessTrace->clear();
2297048Snate@binkert.org    m_macroBlockAccessTrace->clear();
2307048Snate@binkert.org    m_programCounterAccessTrace->clear();
2317048Snate@binkert.org    m_retryProfileMap->clear();
2327048Snate@binkert.org    m_retryProfileHisto.clear();
2337048Snate@binkert.org    m_retryProfileHistoRead.clear();
2347048Snate@binkert.org    m_retryProfileHistoWrite.clear();
2357048Snate@binkert.org    m_getx_sharing_histogram.clear();
2367048Snate@binkert.org    m_gets_sharing_histogram.clear();
2376145Snate@binkert.org}
2386145Snate@binkert.org
2397048Snate@binkert.orgvoid
2407048Snate@binkert.orgAddressProfiler::profileGetX(const Address& datablock, const Address& PC,
2417048Snate@binkert.org                             const Set& owner, const Set& sharers,
2427048Snate@binkert.org                             NodeID requestor)
2436145Snate@binkert.org{
2447048Snate@binkert.org    Set indirection_set;
2457048Snate@binkert.org    indirection_set.addSet(sharers);
2467048Snate@binkert.org    indirection_set.addSet(owner);
2477048Snate@binkert.org    indirection_set.remove(requestor);
2487048Snate@binkert.org    int num_indirections = indirection_set.count();
2496145Snate@binkert.org
2507048Snate@binkert.org    m_getx_sharing_histogram.add(num_indirections);
2517048Snate@binkert.org    bool indirection_miss = (num_indirections > 0);
2526145Snate@binkert.org
2537048Snate@binkert.org    addTraceSample(datablock, PC, CacheRequestType_ST, AccessModeType(0),
2547048Snate@binkert.org                   requestor, indirection_miss);
2556145Snate@binkert.org}
2566145Snate@binkert.org
2577048Snate@binkert.orgvoid
2587048Snate@binkert.orgAddressProfiler::profileGetS(const Address& datablock, const Address& PC,
2597048Snate@binkert.org                             const Set& owner, const Set& sharers,
2607048Snate@binkert.org                             NodeID requestor)
2616145Snate@binkert.org{
2627048Snate@binkert.org    Set indirection_set;
2637048Snate@binkert.org    indirection_set.addSet(owner);
2647048Snate@binkert.org    indirection_set.remove(requestor);
2657048Snate@binkert.org    int num_indirections = indirection_set.count();
2667048Snate@binkert.org
2677048Snate@binkert.org    m_gets_sharing_histogram.add(num_indirections);
2687048Snate@binkert.org    bool indirection_miss = (num_indirections > 0);
2697048Snate@binkert.org
2707048Snate@binkert.org    addTraceSample(datablock, PC, CacheRequestType_LD, AccessModeType(0),
2717048Snate@binkert.org                   requestor, indirection_miss);
2727048Snate@binkert.org}
2737048Snate@binkert.org
2747048Snate@binkert.orgvoid
2757048Snate@binkert.orgAddressProfiler::addTraceSample(Address data_addr, Address pc_addr,
2767048Snate@binkert.org                                CacheRequestType type,
2777048Snate@binkert.org                                AccessModeType access_mode, NodeID id,
2787048Snate@binkert.org                                bool sharing_miss)
2797048Snate@binkert.org{
2807048Snate@binkert.org    if (m_all_instructions) {
2817048Snate@binkert.org        if (sharing_miss) {
2827048Snate@binkert.org            m_sharing_miss_counter++;
2837048Snate@binkert.org        }
2847048Snate@binkert.org
2857048Snate@binkert.org        // record data address trace info
2867048Snate@binkert.org        data_addr.makeLineAddress();
2877048Snate@binkert.org        lookupTraceForAddress(data_addr, m_dataAccessTrace).
2887048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
2897048Snate@binkert.org
2907048Snate@binkert.org        // record macro data address trace info
2917048Snate@binkert.org
2927048Snate@binkert.org        // 6 for datablock, 4 to make it 16x more coarse
2937048Snate@binkert.org        Address macro_addr(data_addr.maskLowOrderBits(10));
2947048Snate@binkert.org        lookupTraceForAddress(macro_addr, m_macroBlockAccessTrace).
2957048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
2967048Snate@binkert.org
2977048Snate@binkert.org        // record program counter address trace info
2987048Snate@binkert.org        lookupTraceForAddress(pc_addr, m_programCounterAccessTrace).
2997048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
3006145Snate@binkert.org    }
3016145Snate@binkert.org
3027048Snate@binkert.org    if (m_all_instructions) {
3037048Snate@binkert.org        // This code is used if the address profiler is an
3047048Snate@binkert.org        // all-instructions profiler record program counter address
3057048Snate@binkert.org        // trace info
3067048Snate@binkert.org        lookupTraceForAddress(pc_addr, m_programCounterAccessTrace).
3077048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
3087048Snate@binkert.org    }
3096145Snate@binkert.org}
3106145Snate@binkert.org
3117048Snate@binkert.orgvoid
3127048Snate@binkert.orgAddressProfiler::profileRetry(const Address& data_addr, AccessType type,
3137048Snate@binkert.org                              int count)
3146145Snate@binkert.org{
3157048Snate@binkert.org    m_retryProfileHisto.add(count);
3167048Snate@binkert.org    if (type == AccessType_Read) {
3177048Snate@binkert.org        m_retryProfileHistoRead.add(count);
3187048Snate@binkert.org    } else {
3197048Snate@binkert.org        m_retryProfileHistoWrite.add(count);
3207048Snate@binkert.org    }
3217048Snate@binkert.org    if (count > 1) {
3227048Snate@binkert.org        lookupTraceForAddress(data_addr, m_retryProfileMap).addSample(count);
3237048Snate@binkert.org    }
3246145Snate@binkert.org}
325