AddressProfiler.cc revision 7054
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
377048Snate@binkert.orgtypedef AddressProfiler::AddressMap AddressMap;
386145Snate@binkert.org
396145Snate@binkert.org// Helper functions
407048Snate@binkert.orgAccessTraceForAddress&
417048Snate@binkert.orglookupTraceForAddress(const Address& addr, AddressMap* record_map)
427048Snate@binkert.org{
437048Snate@binkert.org    if (!record_map->exist(addr)) {
447048Snate@binkert.org        record_map->add(addr, AccessTraceForAddress(addr));
457048Snate@binkert.org    }
467048Snate@binkert.org    return record_map->lookup(addr);
477048Snate@binkert.org}
486145Snate@binkert.org
497048Snate@binkert.orgvoid
507054Snate@binkert.orgprintSorted(ostream& out, int num_of_sequencers, const AddressMap* record_map,
517048Snate@binkert.org            string description)
527048Snate@binkert.org{
537048Snate@binkert.org    const int records_printed = 100;
547048Snate@binkert.org
557048Snate@binkert.org    uint64 misses = 0;
567048Snate@binkert.org    PrioHeap<AccessTraceForAddress*> heap;
577048Snate@binkert.org    Vector<Address> keys = record_map->keys();
587048Snate@binkert.org    for (int i = 0; i < keys.size(); i++) {
597048Snate@binkert.org        AccessTraceForAddress* record = &(record_map->lookup(keys[i]));
607048Snate@binkert.org        misses += record->getTotal();
617048Snate@binkert.org        heap.insert(record);
627048Snate@binkert.org    }
637048Snate@binkert.org
647048Snate@binkert.org    out << "Total_entries_" << description << ": " << keys.size() << endl;
657048Snate@binkert.org    if (g_system_ptr->getProfiler()->getAllInstructions())
667048Snate@binkert.org        out << "Total_Instructions_" << description << ": " << misses << endl;
677048Snate@binkert.org    else
687048Snate@binkert.org        out << "Total_data_misses_" << description << ": " << misses << endl;
697048Snate@binkert.org
707048Snate@binkert.org    out << "total | load store atomic | user supervisor | sharing | touched-by"
717048Snate@binkert.org        << endl;
727048Snate@binkert.org
737048Snate@binkert.org    Histogram remaining_records(1, 100);
747048Snate@binkert.org    Histogram all_records(1, 100);
757048Snate@binkert.org    Histogram remaining_records_log(-1);
767048Snate@binkert.org    Histogram all_records_log(-1);
777048Snate@binkert.org
787048Snate@binkert.org    // Allows us to track how many lines where touched by n processors
797048Snate@binkert.org    Vector<int64> m_touched_vec;
807048Snate@binkert.org    Vector<int64> m_touched_weighted_vec;
817048Snate@binkert.org    m_touched_vec.setSize(num_of_sequencers+1);
827048Snate@binkert.org    m_touched_weighted_vec.setSize(num_of_sequencers+1);
837048Snate@binkert.org    for (int i = 0; i < m_touched_vec.size(); i++) {
847048Snate@binkert.org        m_touched_vec[i] = 0;
857048Snate@binkert.org        m_touched_weighted_vec[i] = 0;
867048Snate@binkert.org    }
877048Snate@binkert.org
887048Snate@binkert.org    int counter = 0;
897048Snate@binkert.org    while (heap.size() > 0 && counter < records_printed) {
907048Snate@binkert.org        AccessTraceForAddress* record = heap.extractMin();
917048Snate@binkert.org        double percent = 100.0 * (record->getTotal() / double(misses));
927048Snate@binkert.org        out << description << " | " << percent << " % " << *record << endl;
937048Snate@binkert.org        all_records.add(record->getTotal());
947048Snate@binkert.org        all_records_log.add(record->getTotal());
957048Snate@binkert.org        counter++;
967048Snate@binkert.org        m_touched_vec[record->getTouchedBy()]++;
977048Snate@binkert.org        m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
987048Snate@binkert.org    }
997048Snate@binkert.org
1007048Snate@binkert.org    while (heap.size() > 0) {
1017048Snate@binkert.org        AccessTraceForAddress* record = heap.extractMin();
1027048Snate@binkert.org        all_records.add(record->getTotal());
1037048Snate@binkert.org        remaining_records.add(record->getTotal());
1047048Snate@binkert.org        all_records_log.add(record->getTotal());
1057048Snate@binkert.org        remaining_records_log.add(record->getTotal());
1067048Snate@binkert.org        m_touched_vec[record->getTouchedBy()]++;
1077048Snate@binkert.org        m_touched_weighted_vec[record->getTouchedBy()] += record->getTotal();
1087048Snate@binkert.org    }
1097048Snate@binkert.org    out << endl;
1107048Snate@binkert.org    out << "all_records_" << description << ": "
1117048Snate@binkert.org        << all_records << endl
1127048Snate@binkert.org        << "all_records_log_" << description << ": "
1137048Snate@binkert.org        << all_records_log << endl
1147048Snate@binkert.org        << "remaining_records_" << description << ": "
1157048Snate@binkert.org        << remaining_records << endl
1167048Snate@binkert.org        << "remaining_records_log_" << description << ": "
1177048Snate@binkert.org        << remaining_records_log << endl
1187048Snate@binkert.org        << "touched_by_" << description << ": "
1197048Snate@binkert.org        << m_touched_vec << endl
1207048Snate@binkert.org        << "touched_by_weighted_" << description << ": "
1217048Snate@binkert.org        << m_touched_weighted_vec << endl
1227048Snate@binkert.org        << endl;
1237048Snate@binkert.org}
1246896SBrad.Beckmann@amd.com
1256896SBrad.Beckmann@amd.comAddressProfiler::AddressProfiler(int num_of_sequencers)
1266145Snate@binkert.org{
1277048Snate@binkert.org    m_dataAccessTrace = new AddressMap;
1287048Snate@binkert.org    m_macroBlockAccessTrace = new AddressMap;
1297048Snate@binkert.org    m_programCounterAccessTrace = new AddressMap;
1307048Snate@binkert.org    m_retryProfileMap = new AddressMap;
1317048Snate@binkert.org    m_num_of_sequencers = num_of_sequencers;
1327048Snate@binkert.org    clearStats();
1336145Snate@binkert.org}
1346145Snate@binkert.org
1356145Snate@binkert.orgAddressProfiler::~AddressProfiler()
1366145Snate@binkert.org{
1377048Snate@binkert.org    delete m_dataAccessTrace;
1387048Snate@binkert.org    delete m_macroBlockAccessTrace;
1397048Snate@binkert.org    delete m_programCounterAccessTrace;
1407048Snate@binkert.org    delete m_retryProfileMap;
1416145Snate@binkert.org}
1426145Snate@binkert.org
1437048Snate@binkert.orgvoid
1447048Snate@binkert.orgAddressProfiler::setHotLines(bool hot_lines)
1457048Snate@binkert.org{
1467048Snate@binkert.org    m_hot_lines = hot_lines;
1476285Snate@binkert.org}
1486285Snate@binkert.org
1497048Snate@binkert.orgvoid
1507048Snate@binkert.orgAddressProfiler::setAllInstructions(bool all_instructions)
1516145Snate@binkert.org{
1527048Snate@binkert.org    m_all_instructions = all_instructions;
1536145Snate@binkert.org}
1546145Snate@binkert.org
1557048Snate@binkert.orgvoid
1567048Snate@binkert.orgAddressProfiler::printStats(ostream& out) const
1576145Snate@binkert.org{
1587048Snate@binkert.org    if (m_hot_lines) {
1597048Snate@binkert.org        out << endl;
1607048Snate@binkert.org        out << "AddressProfiler Stats" << endl;
1617048Snate@binkert.org        out << "---------------------" << endl;
1627048Snate@binkert.org
1637048Snate@binkert.org        out << endl;
1647048Snate@binkert.org        out << "sharing_misses: " << m_sharing_miss_counter << endl;
1657048Snate@binkert.org        out << "getx_sharing_histogram: " << m_getx_sharing_histogram << endl;
1667048Snate@binkert.org        out << "gets_sharing_histogram: " << m_gets_sharing_histogram << endl;
1677048Snate@binkert.org
1687048Snate@binkert.org        out << endl;
1697048Snate@binkert.org        out << "Hot Data Blocks" << endl;
1707048Snate@binkert.org        out << "---------------" << endl;
1717048Snate@binkert.org        out << endl;
1727048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_dataAccessTrace,
1737048Snate@binkert.org                    "block_address");
1747048Snate@binkert.org
1757048Snate@binkert.org        out << endl;
1767048Snate@binkert.org        out << "Hot MacroData Blocks" << endl;
1777048Snate@binkert.org        out << "--------------------" << endl;
1787048Snate@binkert.org        out << endl;
1797048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_macroBlockAccessTrace,
1807048Snate@binkert.org                    "macroblock_address");
1817048Snate@binkert.org
1827048Snate@binkert.org        out << "Hot Instructions" << endl;
1837048Snate@binkert.org        out << "----------------" << endl;
1847048Snate@binkert.org        out << endl;
1857048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
1867048Snate@binkert.org                    "pc_address");
1877048Snate@binkert.org    }
1887048Snate@binkert.org
1897048Snate@binkert.org    if (m_all_instructions) {
1907048Snate@binkert.org        out << endl;
1917048Snate@binkert.org        out << "All Instructions Profile:" << endl;
1927048Snate@binkert.org        out << "-------------------------" << endl;
1937048Snate@binkert.org        out << endl;
1947048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
1957048Snate@binkert.org                    "pc_address");
1967048Snate@binkert.org        out << endl;
1977048Snate@binkert.org    }
1987048Snate@binkert.org
1997048Snate@binkert.org    if (m_retryProfileHisto.size() > 0) {
2007048Snate@binkert.org        out << "Retry Profile" << endl;
2017048Snate@binkert.org        out << "-------------" << endl;
2027048Snate@binkert.org        out << endl;
2037048Snate@binkert.org        out << "retry_histogram_absolute: " << m_retryProfileHisto << endl;
2047048Snate@binkert.org        out << "retry_histogram_write: " << m_retryProfileHistoWrite << endl;
2057048Snate@binkert.org        out << "retry_histogram_read: " << m_retryProfileHistoRead << endl;
2067048Snate@binkert.org
2077048Snate@binkert.org        out << "retry_histogram_percent: ";
2087048Snate@binkert.org        m_retryProfileHisto.printPercent(out);
2097048Snate@binkert.org        out << endl;
2107048Snate@binkert.org
2117048Snate@binkert.org        printSorted(out, m_num_of_sequencers, m_retryProfileMap,
2127048Snate@binkert.org                    "block_address");
2137048Snate@binkert.org        out << endl;
2147048Snate@binkert.org    }
2156145Snate@binkert.org}
2166145Snate@binkert.org
2177048Snate@binkert.orgvoid
2187048Snate@binkert.orgAddressProfiler::clearStats()
2196145Snate@binkert.org{
2207048Snate@binkert.org    // Clear the maps
2217048Snate@binkert.org    m_sharing_miss_counter = 0;
2227048Snate@binkert.org    m_dataAccessTrace->clear();
2237048Snate@binkert.org    m_macroBlockAccessTrace->clear();
2247048Snate@binkert.org    m_programCounterAccessTrace->clear();
2257048Snate@binkert.org    m_retryProfileMap->clear();
2267048Snate@binkert.org    m_retryProfileHisto.clear();
2277048Snate@binkert.org    m_retryProfileHistoRead.clear();
2287048Snate@binkert.org    m_retryProfileHistoWrite.clear();
2297048Snate@binkert.org    m_getx_sharing_histogram.clear();
2307048Snate@binkert.org    m_gets_sharing_histogram.clear();
2316145Snate@binkert.org}
2326145Snate@binkert.org
2337048Snate@binkert.orgvoid
2347048Snate@binkert.orgAddressProfiler::profileGetX(const Address& datablock, const Address& PC,
2357048Snate@binkert.org                             const Set& owner, const Set& sharers,
2367048Snate@binkert.org                             NodeID requestor)
2376145Snate@binkert.org{
2387048Snate@binkert.org    Set indirection_set;
2397048Snate@binkert.org    indirection_set.addSet(sharers);
2407048Snate@binkert.org    indirection_set.addSet(owner);
2417048Snate@binkert.org    indirection_set.remove(requestor);
2427048Snate@binkert.org    int num_indirections = indirection_set.count();
2436145Snate@binkert.org
2447048Snate@binkert.org    m_getx_sharing_histogram.add(num_indirections);
2457048Snate@binkert.org    bool indirection_miss = (num_indirections > 0);
2466145Snate@binkert.org
2477048Snate@binkert.org    addTraceSample(datablock, PC, CacheRequestType_ST, AccessModeType(0),
2487048Snate@binkert.org                   requestor, indirection_miss);
2496145Snate@binkert.org}
2506145Snate@binkert.org
2517048Snate@binkert.orgvoid
2527048Snate@binkert.orgAddressProfiler::profileGetS(const Address& datablock, const Address& PC,
2537048Snate@binkert.org                             const Set& owner, const Set& sharers,
2547048Snate@binkert.org                             NodeID requestor)
2556145Snate@binkert.org{
2567048Snate@binkert.org    Set indirection_set;
2577048Snate@binkert.org    indirection_set.addSet(owner);
2587048Snate@binkert.org    indirection_set.remove(requestor);
2597048Snate@binkert.org    int num_indirections = indirection_set.count();
2607048Snate@binkert.org
2617048Snate@binkert.org    m_gets_sharing_histogram.add(num_indirections);
2627048Snate@binkert.org    bool indirection_miss = (num_indirections > 0);
2637048Snate@binkert.org
2647048Snate@binkert.org    addTraceSample(datablock, PC, CacheRequestType_LD, AccessModeType(0),
2657048Snate@binkert.org                   requestor, indirection_miss);
2667048Snate@binkert.org}
2677048Snate@binkert.org
2687048Snate@binkert.orgvoid
2697048Snate@binkert.orgAddressProfiler::addTraceSample(Address data_addr, Address pc_addr,
2707048Snate@binkert.org                                CacheRequestType type,
2717048Snate@binkert.org                                AccessModeType access_mode, NodeID id,
2727048Snate@binkert.org                                bool sharing_miss)
2737048Snate@binkert.org{
2747048Snate@binkert.org    if (m_all_instructions) {
2757048Snate@binkert.org        if (sharing_miss) {
2767048Snate@binkert.org            m_sharing_miss_counter++;
2777048Snate@binkert.org        }
2787048Snate@binkert.org
2797048Snate@binkert.org        // record data address trace info
2807048Snate@binkert.org        data_addr.makeLineAddress();
2817048Snate@binkert.org        lookupTraceForAddress(data_addr, m_dataAccessTrace).
2827048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
2837048Snate@binkert.org
2847048Snate@binkert.org        // record macro data address trace info
2857048Snate@binkert.org
2867048Snate@binkert.org        // 6 for datablock, 4 to make it 16x more coarse
2877048Snate@binkert.org        Address macro_addr(data_addr.maskLowOrderBits(10));
2887048Snate@binkert.org        lookupTraceForAddress(macro_addr, m_macroBlockAccessTrace).
2897048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
2907048Snate@binkert.org
2917048Snate@binkert.org        // record program counter address trace info
2927048Snate@binkert.org        lookupTraceForAddress(pc_addr, m_programCounterAccessTrace).
2937048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
2946145Snate@binkert.org    }
2956145Snate@binkert.org
2967048Snate@binkert.org    if (m_all_instructions) {
2977048Snate@binkert.org        // This code is used if the address profiler is an
2987048Snate@binkert.org        // all-instructions profiler record program counter address
2997048Snate@binkert.org        // trace info
3007048Snate@binkert.org        lookupTraceForAddress(pc_addr, m_programCounterAccessTrace).
3017048Snate@binkert.org            update(type, access_mode, id, sharing_miss);
3027048Snate@binkert.org    }
3036145Snate@binkert.org}
3046145Snate@binkert.org
3057048Snate@binkert.orgvoid
3067048Snate@binkert.orgAddressProfiler::profileRetry(const Address& data_addr, AccessType type,
3077048Snate@binkert.org                              int count)
3086145Snate@binkert.org{
3097048Snate@binkert.org    m_retryProfileHisto.add(count);
3107048Snate@binkert.org    if (type == AccessType_Read) {
3117048Snate@binkert.org        m_retryProfileHistoRead.add(count);
3127048Snate@binkert.org    } else {
3137048Snate@binkert.org        m_retryProfileHistoWrite.add(count);
3147048Snate@binkert.org    }
3157048Snate@binkert.org    if (count > 1) {
3167048Snate@binkert.org        lookupTraceForAddress(data_addr, m_retryProfileMap).addSample(count);
3177048Snate@binkert.org    }
3186145Snate@binkert.org}
319