diff options
author | Derek Hower <drh5@cs.wisc.edu> | 2009-07-20 09:40:43 -0500 |
---|---|---|
committer | Derek Hower <drh5@cs.wisc.edu> | 2009-07-20 09:40:43 -0500 |
commit | e59d0e3e89f46f35065ab318c8578941203cc657 (patch) | |
tree | 73dc7c9e8bd34c71712628326b4c9de69d4658c1 /src/mem | |
parent | 308419b947b46f065b7e539040a1a2ef89be6480 (diff) | |
download | gem5-e59d0e3e89f46f35065ab318c8578941203cc657.tar.xz |
ruby: moved cache stats from Profiler to CacheMemory
Caches are now responsible for their own statistic gathering. This
requires a direct callback from the protocol on misses, and so all
future protocols need to take this into account.
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/protocol/MI_example-cache.sm | 9 | ||||
-rw-r--r-- | src/mem/ruby/profiler/CacheProfiler.cc | 20 | ||||
-rw-r--r-- | src/mem/ruby/profiler/CacheProfiler.hh | 4 | ||||
-rw-r--r-- | src/mem/ruby/profiler/Profiler.cc | 82 | ||||
-rw-r--r-- | src/mem/ruby/profiler/Profiler.hh | 9 | ||||
-rw-r--r-- | src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc | 22 | ||||
-rw-r--r-- | src/mem/ruby/system/CacheMemory.hh | 22 | ||||
-rw-r--r-- | src/mem/ruby/system/System.cc | 4 |
8 files changed, 46 insertions, 126 deletions
diff --git a/src/mem/protocol/MI_example-cache.sm b/src/mem/protocol/MI_example-cache.sm index ae8ab519f..16a158f0d 100644 --- a/src/mem/protocol/MI_example-cache.sm +++ b/src/mem/protocol/MI_example-cache.sm @@ -58,6 +58,7 @@ machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY LATENCY Entry lookup(Address); void changePermission(Address, AccessPermission); bool isTagPresent(Address); + void profileMiss(CacheMsg); } // TBE fields @@ -259,6 +260,12 @@ machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY LATENCY profileMsgDelay(2, forwardRequestNetwork_in.dequeue_getDelayCycles()); } + action(p_profileMiss, "p", desc="Profile cache miss") { + peek(mandatoryQueue_in, CacheMsg) { + cacheMemory.profileMiss(in_msg); + } + } + action(r_load_hit, "r", desc="Notify sequencer the load completed.") { DEBUG_EXPR(cacheMemory[address].DataBlk); sequencer.readCallback(address, cacheMemory[address].DataBlk); @@ -326,6 +333,7 @@ machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY LATENCY v_allocateTBE; i_allocateL1CacheBlock; a_issueRequest; + p_profileMiss; m_popMandatoryQueue; } @@ -333,6 +341,7 @@ machine(L1Cache, "MI Example L1 Cache"): LATENCY_CACHE_RESPONSE_LATENCY LATENCY v_allocateTBE; i_allocateL1CacheBlock; a_issueRequest; + p_profileMiss; m_popMandatoryQueue; } diff --git a/src/mem/ruby/profiler/CacheProfiler.cc b/src/mem/ruby/profiler/CacheProfiler.cc index 516e73ae9..fad8d51b4 100644 --- a/src/mem/ruby/profiler/CacheProfiler.cc +++ b/src/mem/ruby/profiler/CacheProfiler.cc @@ -48,7 +48,7 @@ CacheProfiler::CacheProfiler(string description) { m_description = description; m_requestTypeVec_ptr = new Vector<int>; - m_requestTypeVec_ptr->setSize(int(GenericRequestType_NUM)); + m_requestTypeVec_ptr->setSize(int(CacheRequestType_NUM)); clearStats(); } @@ -70,30 +70,22 @@ void CacheProfiler::printStats(ostream& out) const out << description << "_total_hw_prefetches: " << m_hw_prefetches << endl; double trans_executed = double(g_system_ptr->getProfiler()->getTotalTransactionsExecuted()); - double inst_executed = double(g_system_ptr->getProfiler()->getTotalInstructionsExecuted()); out << description << "_misses_per_transaction: " << double(m_misses) / trans_executed << endl; - out << description << "_misses_per_instruction: " << double(m_misses) / inst_executed << endl; - out << description << "_instructions_per_misses: "; - if (m_misses > 0) { - out << inst_executed / double(m_misses) << endl; - } else { - out << "NaN" << endl; - } out << endl; int requests = 0; - for(int i=0; i<int(GenericRequestType_NUM); i++) { + for(int i=0; i<int(CacheRequestType_NUM); i++) { requests += m_requestTypeVec_ptr->ref(i); } assert(m_misses == requests); if (requests > 0) { - for(int i=0; i<int(GenericRequestType_NUM); i++){ + for(int i=0; i<int(CacheRequestType_NUM); i++){ if (m_requestTypeVec_ptr->ref(i) > 0) { - out << description << "_request_type_" << GenericRequestType_to_string(GenericRequestType(i)) << ": " + out << description << "_request_type_" << CacheRequestType_to_string(CacheRequestType(i)) << ": " << (100.0 * double((m_requestTypeVec_ptr->ref(i)))) / double(requests) << "%" << endl; } @@ -116,7 +108,7 @@ void CacheProfiler::printStats(ostream& out) const void CacheProfiler::clearStats() { - for(int i=0; i<int(GenericRequestType_NUM); i++) { + for(int i=0; i<int(CacheRequestType_NUM); i++) { m_requestTypeVec_ptr->ref(i) = 0; } m_requestSize.clear(); @@ -130,7 +122,7 @@ void CacheProfiler::clearStats() } } -void CacheProfiler::addStatSample(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit) +void CacheProfiler::addStatSample(CacheRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit) { m_misses++; diff --git a/src/mem/ruby/profiler/CacheProfiler.hh b/src/mem/ruby/profiler/CacheProfiler.hh index 00beeb484..6d7c163cb 100644 --- a/src/mem/ruby/profiler/CacheProfiler.hh +++ b/src/mem/ruby/profiler/CacheProfiler.hh @@ -44,7 +44,7 @@ #include "mem/ruby/common/Histogram.hh" #include "mem/protocol/AccessModeType.hh" #include "mem/protocol/PrefetchBit.hh" -#include "mem/protocol/GenericRequestType.hh" +#include "mem/protocol/CacheRequestType.hh" template <class TYPE> class Vector; @@ -60,7 +60,7 @@ public: void printStats(ostream& out) const; void clearStats(); - void addStatSample(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit); + void addStatSample(CacheRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit); void print(ostream& out) const; private: diff --git a/src/mem/ruby/profiler/Profiler.cc b/src/mem/ruby/profiler/Profiler.cc index 51e3e8398..e8aa7edf9 100644 --- a/src/mem/ruby/profiler/Profiler.cc +++ b/src/mem/ruby/profiler/Profiler.cc @@ -380,9 +380,9 @@ void Profiler::printStats(ostream& out, bool short_stats) out << endl; - m_L1D_cache_profiler_ptr->printStats(out); - m_L1I_cache_profiler_ptr->printStats(out); - m_L2_cache_profiler_ptr->printStats(out); + // m_L1D_cache_profiler_ptr->printStats(out); + // m_L1I_cache_profiler_ptr->printStats(out); + // m_L2_cache_profiler_ptr->printStats(out); out << endl; @@ -773,25 +773,6 @@ void Profiler::clearStats() m_ruby_start = g_eventQueue_ptr->getTime(); } -void Profiler::addPrimaryStatSample(const CacheMsg& msg, NodeID id) -{ - if (Protocol::m_TwoLevelCache) { - if (msg.getType() == CacheRequestType_IFETCH) { - addL1IStatSample(msg, id); - } else { - addL1DStatSample(msg, id); - } - // profile the address after an L1 miss (outside of the processor for CMP) - if (Protocol::m_CMP) { - addAddressTraceSample(msg, id); - } - } else { - addL2StatSample(CacheRequestType_to_GenericRequestType(msg.getType()), - msg.getAccessMode(), msg.getSize(), msg.getPrefetch(), id); - addAddressTraceSample(msg, id); - } -} - void Profiler::profileConflictingRequests(const Address& addr) { assert(addr == line_address(addr)); @@ -805,39 +786,6 @@ void Profiler::profileConflictingRequests(const Address& addr) m_conflicting_map_ptr->add(addr, current_time); } -void Profiler::addSecondaryStatSample(CacheRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id) -{ - addSecondaryStatSample(CacheRequestType_to_GenericRequestType(requestType), type, msgSize, pfBit, id); -} - -void Profiler::addSecondaryStatSample(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id) -{ - addL2StatSample(requestType, type, msgSize, pfBit, id); -} - -void Profiler::addL2StatSample(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id) -{ - m_perProcTotalMisses[id]++; - if (type == AccessModeType_SupervisorMode) { - m_perProcSupervisorMisses[id]++; - } else { - m_perProcUserMisses[id]++; - } - m_L2_cache_profiler_ptr->addStatSample(requestType, type, msgSize, pfBit); -} - -void Profiler::addL1DStatSample(const CacheMsg& msg, NodeID id) -{ - m_L1D_cache_profiler_ptr->addStatSample(CacheRequestType_to_GenericRequestType(msg.getType()), - msg.getAccessMode(), msg.getSize(), msg.getPrefetch()); -} - -void Profiler::addL1IStatSample(const CacheMsg& msg, NodeID id) -{ - m_L1I_cache_profiler_ptr->addStatSample(CacheRequestType_to_GenericRequestType(msg.getType()), - msg.getAccessMode(), msg.getSize(), msg.getPrefetch()); -} - void Profiler::addAddressTraceSample(const CacheMsg& msg, NodeID id) { if (msg.getType() != CacheRequestType_IFETCH) { @@ -1055,30 +1003,6 @@ int64 Profiler::getTotalTransactionsExecuted() const } -// The following case statement converts CacheRequestTypes to GenericRequestTypes -// allowing all profiling to be done with a single enum type instead of slow strings -GenericRequestType Profiler::CacheRequestType_to_GenericRequestType(const CacheRequestType& type) { - switch (type) { - case CacheRequestType_LD: - return GenericRequestType_LD; - break; - case CacheRequestType_ST: - return GenericRequestType_ST; - break; - case CacheRequestType_ATOMIC: - return GenericRequestType_ATOMIC; - break; - case CacheRequestType_IFETCH: - return GenericRequestType_IFETCH; - break; - case CacheRequestType_NULL: - return GenericRequestType_NULL; - break; - default: - ERROR_MSG("Unexpected cache request type"); - } -} - void Profiler::rubyWatch(int id){ //int rn_g1 = 0;//SIMICS_get_register_number(id, "g1"); uint64 tr = 0;//SIMICS_read_register(id, rn_g1); diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh index e04994fcb..4549e3ea7 100644 --- a/src/mem/ruby/profiler/Profiler.hh +++ b/src/mem/ruby/profiler/Profiler.hh @@ -126,9 +126,6 @@ public: AddressProfiler* getAddressProfiler() { return m_address_profiler_ptr; } AddressProfiler* getInstructionProfiler() { return m_inst_profiler_ptr; } - void addPrimaryStatSample(const CacheMsg& msg, NodeID id); - void addSecondaryStatSample(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id); - void addSecondaryStatSample(CacheRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id); void addAddressTraceSample(const CacheMsg& msg, NodeID id); void profileRequest(const string& requestStr); @@ -206,12 +203,6 @@ public: private: //added by SS vector<string> m_memory_control_names; - // Private Methods - void addL2StatSample(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID id); - void addL1DStatSample(const CacheMsg& msg, NodeID id); - void addL1IStatSample(const CacheMsg& msg, NodeID id); - - GenericRequestType CacheRequestType_to_GenericRequestType(const CacheRequestType& type); // Private copy constructor and assignment operator Profiler(const Profiler& obj); diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc index 6a12af385..883edd3c8 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc +++ b/src/mem/ruby/slicc_interface/RubySlicc_Profiler_interface.cc @@ -79,33 +79,11 @@ void profile_sharing(const Address& addr, AccessType type, NodeID requestor, con g_system_ptr->getProfiler()->profileSharing(addr, type, requestor, sharers, owner); } -void profile_miss(const CacheMsg& msg, NodeID id) -{ - // CMP profile address after L1 misses, not L2 - ASSERT (!Protocol::m_CMP); - g_system_ptr->getProfiler()->addAddressTraceSample(msg, id); - - g_system_ptr->getProfiler()->profileConflictingRequests(msg.getLineAddress()); - - g_system_ptr->getProfiler()->addSecondaryStatSample(msg.getType(), - msg.getAccessMode(), msg.getSize(), msg.getPrefetch(), id); -} - -void profile_L1Cache_miss(const CacheMsg& msg, NodeID id) -{ - g_system_ptr->getProfiler()->addPrimaryStatSample(msg, id); -} - void profileMsgDelay(int virtualNetwork, int delayCycles) { g_system_ptr->getProfiler()->profileMsgDelay(virtualNetwork, delayCycles); } -void profile_L2Cache_miss(GenericRequestType requestType, AccessModeType type, int msgSize, PrefetchBit pfBit, NodeID nodeID) -{ - g_system_ptr->getProfiler()->addSecondaryStatSample(requestType, type, msgSize, pfBit, nodeID); -} - void profile_token_retry(const Address& addr, AccessType type, int count) { g_system_ptr->getProfiler()->getAddressProfiler()->profileRetry(addr, type, count); diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh index c3b7da6ea..cfaa229a5 100644 --- a/src/mem/ruby/system/CacheMemory.hh +++ b/src/mem/ruby/system/CacheMemory.hh @@ -52,6 +52,8 @@ #include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" #include "mem/ruby/system/System.hh" #include "mem/ruby/slicc_interface/AbstractController.hh" +#include "mem/ruby/profiler/CacheProfiler.hh" +#include "mem/protocol/CacheMsg.hh" #include <vector> class CacheMemory { @@ -111,6 +113,8 @@ public: // Set this address to most recently used void setMRU(const Address& address); + void profileMiss(const CacheMsg & msg); + void getMemoryValue(const Address& addr, char* value, unsigned int size_in_bytes ); void setMemoryValue(const Address& addr, char* value, @@ -123,6 +127,8 @@ public: void print(ostream& out) const; void printData(ostream& out) const; + void printStats(ostream& out) const; + private: // Private Methods @@ -154,6 +160,8 @@ private: AbstractReplacementPolicy *m_replacementPolicy_ptr; + CacheProfiler* m_profiler_ptr; + int m_cache_num_sets; int m_cache_num_set_bits; int m_cache_assoc; @@ -182,6 +190,7 @@ inline CacheMemory::CacheMemory(const string & name) : m_cache_name(name) { + m_profiler_ptr = new CacheProfiler(name); } inline @@ -496,6 +505,13 @@ void CacheMemory::setMRU(const Address& address) } inline +void CacheMemory::profileMiss(const CacheMsg & msg) +{ + m_profiler_ptr->addStatSample(msg.getType(), msg.getAccessMode(), + msg.getSize(), msg.getPrefetch()); +} + +inline void CacheMemory::recordCacheContents(CacheRecorder& tr) const { for (int i = 0; i < m_cache_num_sets; i++) { @@ -546,6 +562,12 @@ void CacheMemory::printData(ostream& out) const } inline +void CacheMemory::printStats(ostream& out) const +{ + m_profiler_ptr->printStats(out); +} + +inline void CacheMemory::getMemoryValue(const Address& addr, char* value, unsigned int size_in_bytes ){ AbstractCacheEntry& entry = lookup(line_address(addr)); diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc index fce456607..2c24c9ade 100644 --- a/src/mem/ruby/system/System.cc +++ b/src/mem/ruby/system/System.cc @@ -335,6 +335,10 @@ void RubySystem::printStats(ostream& out) m_profiler_ptr->printStats(out); m_network_ptr->printStats(out); + for (map<string, CacheMemory*>::const_iterator it = m_caches.begin(); + it != m_caches.end(); it++) { + (*it).second->printStats(out); + } for (map<string, AbstractController*>::const_iterator it = m_controllers.begin(); it != m_controllers.end(); it++) { (*it).second->printStats(out); |