diff options
author | Nilay Vaish <nilay@cs.wisc.edu> | 2013-06-25 00:32:03 -0500 |
---|---|---|
committer | Nilay Vaish <nilay@cs.wisc.edu> | 2013-06-25 00:32:03 -0500 |
commit | beb6e57c6f6141ad959bb97b49daad7f1fa54af3 (patch) | |
tree | 3221c7605fee55dc272fc4ba86ad384db9ad41ca /src/mem/ruby/system | |
parent | beee57070a1fecfe4b854af0c525b454a472202f (diff) | |
download | gem5-beb6e57c6f6141ad959bb97b49daad7f1fa54af3.tar.xz |
ruby: profiler: lots of inter-related changes
The patch started of with removing the global variables from the profiler for
profiling the miss latency of requests made to the cache. The corrresponding
histograms have been moved to the Sequencer. These are combined together when
the histograms are printed. Separate histograms are now maintained for
tracking latency of all requests together, of hits only and of misses only.
A particular set of histograms used to use the type GenericMachineType defined
in one of the protocol files. This patch removes this type. Now, everything
that relied on this type would use MachineType instead. To do this, SLICC has
been changed so that multiple machine types can be declared by a controller
in its preamble.
Diffstat (limited to 'src/mem/ruby/system')
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 183 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.hh | 126 |
2 files changed, 216 insertions, 93 deletions
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 606dff0ab..8e61766b8 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -136,6 +136,61 @@ Sequencer::wakeup() void Sequencer::clearStats() { m_outstandReqHist.clear(); + + // Initialize the histograms that track latency of all requests + m_latencyHist.clear(20); + m_typeLatencyHist.resize(RubyRequestType_NUM); + for (int i = 0; i < RubyRequestType_NUM; i++) { + m_typeLatencyHist[i].clear(20); + } + + // Initialize the histograms that track latency of requests that + // hit in the cache attached to the sequencer. + m_hitLatencyHist.clear(20); + m_hitTypeLatencyHist.resize(RubyRequestType_NUM); + m_hitTypeMachLatencyHist.resize(RubyRequestType_NUM); + + for (int i = 0; i < RubyRequestType_NUM; i++) { + m_hitTypeLatencyHist[i].clear(20); + m_hitTypeMachLatencyHist[i].resize(MachineType_NUM); + for (int j = 0; j < MachineType_NUM; j++) { + m_hitTypeMachLatencyHist[i][j].clear(20); + } + } + + // Initialize the histograms that track the latency of requests that + // missed in the cache attached to the sequencer. + m_missLatencyHist.clear(20); + m_missTypeLatencyHist.resize(RubyRequestType_NUM); + m_missTypeMachLatencyHist.resize(RubyRequestType_NUM); + + for (int i = 0; i < RubyRequestType_NUM; i++) { + m_missTypeLatencyHist[i].clear(20); + m_missTypeMachLatencyHist[i].resize(MachineType_NUM); + for (int j = 0; j < MachineType_NUM; j++) { + m_missTypeMachLatencyHist[i][j].clear(20); + } + } + + m_hitMachLatencyHist.resize(MachineType_NUM); + m_missMachLatencyHist.resize(MachineType_NUM); + m_IssueToInitialDelayHist.resize(MachineType_NUM); + m_InitialToForwardDelayHist.resize(MachineType_NUM); + m_ForwardToFirstResponseDelayHist.resize(MachineType_NUM); + m_FirstResponseToCompletionDelayHist.resize(MachineType_NUM); + m_IncompleteTimes.resize(MachineType_NUM); + + for (int i = 0; i < MachineType_NUM; i++) { + m_missMachLatencyHist[i].clear(20); + m_hitMachLatencyHist[i].clear(20); + + m_IssueToInitialDelayHist[i].clear(20); + m_InitialToForwardDelayHist[i].clear(20); + m_ForwardToFirstResponseDelayHist[i].clear(20); + m_FirstResponseToCompletionDelayHist[i].clear(20); + + m_IncompleteTimes[i] = 0; + } } void @@ -370,26 +425,58 @@ Sequencer::handleLlsc(const Address& address, SequencerRequest* request) } void -Sequencer::writeCallback(const Address& address, DataBlock& data) +Sequencer::recordMissLatency(const Cycles cycles, const RubyRequestType type, + const MachineType respondingMach, + bool isExternalHit, Cycles issuedTime, + Cycles initialRequestTime, + Cycles forwardRequestTime, + Cycles firstResponseTime, Cycles completionTime) { - writeCallback(address, GenericMachineType_NULL, data); -} + m_latencyHist.add(cycles); + m_typeLatencyHist[type].add(cycles); + + if (isExternalHit) { + m_missLatencyHist.add(cycles); + m_missTypeLatencyHist[type].add(cycles); + + if (respondingMach != MachineType_NUM) { + m_missMachLatencyHist[respondingMach].add(cycles); + m_missTypeMachLatencyHist[type][respondingMach].add(cycles); + + if ((issuedTime <= initialRequestTime) && + (initialRequestTime <= forwardRequestTime) && + (forwardRequestTime <= firstResponseTime) && + (firstResponseTime <= completionTime)) { + + m_IssueToInitialDelayHist[respondingMach].add( + initialRequestTime - issuedTime); + m_InitialToForwardDelayHist[respondingMach].add( + forwardRequestTime - initialRequestTime); + m_ForwardToFirstResponseDelayHist[respondingMach].add( + firstResponseTime - forwardRequestTime); + m_FirstResponseToCompletionDelayHist[respondingMach].add( + completionTime - firstResponseTime); + } else { + m_IncompleteTimes[respondingMach]++; + } + } + } else { + m_hitLatencyHist.add(cycles); + m_hitTypeLatencyHist[type].add(cycles); -void -Sequencer::writeCallback(const Address& address, - GenericMachineType mach, - DataBlock& data) -{ - writeCallback(address, mach, data, Cycles(0), Cycles(0), Cycles(0)); + if (respondingMach != MachineType_NUM) { + m_hitMachLatencyHist[respondingMach].add(cycles); + m_hitTypeMachLatencyHist[type][respondingMach].add(cycles); + } + } } void -Sequencer::writeCallback(const Address& address, - GenericMachineType mach, - DataBlock& data, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime) +Sequencer::writeCallback(const Address& address, DataBlock& data, + const bool externalHit, const MachineType mach, + const Cycles initialRequestTime, + const Cycles forwardRequestTime, + const Cycles firstResponseTime) { assert(address == line_address(address)); assert(m_writeRequestTable.count(line_address(address))); @@ -427,28 +514,13 @@ Sequencer::writeCallback(const Address& address, m_controller->unblock(address); } - hitCallback(request, mach, data, success, + hitCallback(request, data, success, mach, externalHit, initialRequestTime, forwardRequestTime, firstResponseTime); } void -Sequencer::readCallback(const Address& address, DataBlock& data) -{ - readCallback(address, GenericMachineType_NULL, data); -} - -void -Sequencer::readCallback(const Address& address, - GenericMachineType mach, - DataBlock& data) -{ - readCallback(address, mach, data, Cycles(0), Cycles(0), Cycles(0)); -} - -void -Sequencer::readCallback(const Address& address, - GenericMachineType mach, - DataBlock& data, +Sequencer::readCallback(const Address& address, DataBlock& data, + bool externalHit, const MachineType mach, Cycles initialRequestTime, Cycles forwardRequestTime, Cycles firstResponseTime) @@ -466,18 +538,17 @@ Sequencer::readCallback(const Address& address, assert((request->m_type == RubyRequestType_LD) || (request->m_type == RubyRequestType_IFETCH)); - hitCallback(request, mach, data, true, + hitCallback(request, data, true, mach, externalHit, initialRequestTime, forwardRequestTime, firstResponseTime); } void -Sequencer::hitCallback(SequencerRequest* srequest, - GenericMachineType mach, - DataBlock& data, - bool success, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime) +Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data, + bool llscSuccess, + const MachineType mach, const bool externalHit, + const Cycles initialRequestTime, + const Cycles forwardRequestTime, + const Cycles firstResponseTime) { PacketPtr pkt = srequest->pkt; Address request_address(pkt->getAddr()); @@ -494,29 +565,17 @@ Sequencer::hitCallback(SequencerRequest* srequest, } assert(curCycle() >= issued_time); - Cycles miss_latency = curCycle() - issued_time; - - // Profile the miss latency for all non-zero demand misses - if (miss_latency != 0) { - g_system_ptr->getProfiler()->missLatency(miss_latency, type, mach); + Cycles total_latency = curCycle() - issued_time; - if (mach == GenericMachineType_L1Cache_wCC) { - g_system_ptr->getProfiler()->missLatencyWcc(issued_time, - initialRequestTime, forwardRequestTime, - firstResponseTime, curCycle()); - } - - if (mach == GenericMachineType_Directory) { - g_system_ptr->getProfiler()->missLatencyDir(issued_time, - initialRequestTime, forwardRequestTime, - firstResponseTime, curCycle()); - } + // Profile the latency for all demand accesses. + recordMissLatency(total_latency, type, mach, externalHit, issued_time, + initialRequestTime, forwardRequestTime, + firstResponseTime, curCycle()); - DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %d cycles\n", - curTick(), m_version, "Seq", - success ? "Done" : "SC_Failed", "", "", - request_address, miss_latency); - } + DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %d cycles\n", + curTick(), m_version, "Seq", + llscSuccess ? "Done" : "SC_Failed", "", "", + request_address, total_latency); // update the data if (g_system_ptr->m_warmup_enabled) { diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index 058edb9ce..86e6aa2a9 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -32,7 +32,7 @@ #include <iostream> #include "base/hashmap.hh" -#include "mem/protocol/GenericMachineType.hh" +#include "mem/protocol/MachineType.hh" #include "mem/protocol/RubyRequestType.hh" #include "mem/protocol/SequencerRequestType.hh" #include "mem/ruby/common/Address.hh" @@ -65,36 +65,24 @@ class Sequencer : public RubyPort // Public Methods void wakeup(); // Used only for deadlock detection - void printProgress(std::ostream& out) const; - void clearStats(); - void writeCallback(const Address& address, DataBlock& data); - void writeCallback(const Address& address, - GenericMachineType mach, - DataBlock& data); - - void writeCallback(const Address& address, - GenericMachineType mach, DataBlock& data, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime); - - void readCallback(const Address& address, DataBlock& data); + const bool externalHit = false, + const MachineType mach = MachineType_NUM, + const Cycles initialRequestTime = Cycles(0), + const Cycles forwardRequestTime = Cycles(0), + const Cycles firstResponseTime = Cycles(0)); void readCallback(const Address& address, - GenericMachineType mach, - DataBlock& data); - - void readCallback(const Address& address, - GenericMachineType mach, DataBlock& data, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime); + const bool externalHit = false, + const MachineType mach = MachineType_NUM, + const Cycles initialRequestTime = Cycles(0), + const Cycles forwardRequestTime = Cycles(0), + const Cycles firstResponseTime = Cycles(0)); RequestStatus makeRequest(PacketPtr pkt); bool empty() const; @@ -118,19 +106,63 @@ class Sequencer : public RubyPort void recordRequestType(SequencerRequestType requestType); Histogram& getOutstandReqHist() { return m_outstandReqHist; } + Histogram& getLatencyHist() { return m_latencyHist; } + Histogram& getTypeLatencyHist(uint32_t t) + { return m_typeLatencyHist[t]; } + + Histogram& getHitLatencyHist() { return m_hitLatencyHist; } + Histogram& getHitTypeLatencyHist(uint32_t t) + { return m_hitTypeLatencyHist[t]; } + + Histogram& getHitMachLatencyHist(uint32_t t) + { return m_hitMachLatencyHist[t]; } + + Histogram& getHitTypeMachLatencyHist(uint32_t r, uint32_t t) + { return m_hitTypeMachLatencyHist[r][t]; } + + Histogram& getMissLatencyHist() { return m_missLatencyHist; } + Histogram& getMissTypeLatencyHist(uint32_t t) + { return m_missTypeLatencyHist[t]; } + + Histogram& getMissMachLatencyHist(uint32_t t) + { return m_missMachLatencyHist[t]; } + + Histogram& getMissTypeMachLatencyHist(uint32_t r, uint32_t t) + { return m_missTypeMachLatencyHist[r][t]; } + + Histogram& getIssueToInitialDelayHist(uint32_t t) + { return m_IssueToInitialDelayHist[t]; } + + Histogram& getInitialToForwardDelayHist(const MachineType t) + { return m_InitialToForwardDelayHist[t]; } + + Histogram& getForwardRequestToFirstResponseHist(const MachineType t) + { return m_ForwardToFirstResponseDelayHist[t]; } + + Histogram& getFirstResponseToCompletionDelayHist(const MachineType t) + { return m_FirstResponseToCompletionDelayHist[t]; } + + const uint64_t getIncompleteTimes(const MachineType t) const + { return m_IncompleteTimes[t]; } + private: void issueRequest(PacketPtr pkt, RubyRequestType type); - void hitCallback(SequencerRequest* request, - GenericMachineType mach, - DataBlock& data, - bool success, - Cycles initialRequestTime, - Cycles forwardRequestTime, - Cycles firstResponseTime); + void hitCallback(SequencerRequest* request, DataBlock& data, + bool llscSuccess, + const MachineType mach, const bool externalHit, + const Cycles initialRequestTime, + const Cycles forwardRequestTime, + const Cycles firstResponseTime); - RequestStatus insertRequest(PacketPtr pkt, RubyRequestType request_type); + void recordMissLatency(const Cycles t, const RubyRequestType type, + const MachineType respondingMach, + bool isExternalHit, Cycles issuedTime, + Cycles initialRequestTime, + Cycles forwardRequestTime, Cycles firstResponseTime, + Cycles completionTime); + RequestStatus insertRequest(PacketPtr pkt, RubyRequestType request_type); bool handleLlsc(const Address& address, SequencerRequest* request); // Private copy constructor and assignment operator @@ -161,6 +193,38 @@ class Sequencer : public RubyPort //! Histogram for number of outstanding requests per cycle. Histogram m_outstandReqHist; + //! Histogram for holding latency profile of all requests. + Histogram m_latencyHist; + std::vector<Histogram> m_typeLatencyHist; + + //! Histogram for holding latency profile of all requests that + //! hit in the controller connected to this sequencer. + Histogram m_hitLatencyHist; + std::vector<Histogram> m_hitTypeLatencyHist; + + //! Histograms for profiling the latencies for requests that + //! did not required external messages. + std::vector<Histogram> m_hitMachLatencyHist; + std::vector< std::vector<Histogram> > m_hitTypeMachLatencyHist; + + //! Histogram for holding latency profile of all requests that + //! miss in the controller connected to this sequencer. + Histogram m_missLatencyHist; + std::vector<Histogram> m_missTypeLatencyHist; + + //! Histograms for profiling the latencies for requests that + //! required external messages. + std::vector<Histogram> m_missMachLatencyHist; + std::vector< std::vector<Histogram> > m_missTypeMachLatencyHist; + + //! Histograms for recording the breakdown of miss latency + std::vector<Histogram> m_IssueToInitialDelayHist; + std::vector<Histogram> m_InitialToForwardDelayHist; + std::vector<Histogram> m_ForwardToFirstResponseDelayHist; + std::vector<Histogram> m_FirstResponseToCompletionDelayHist; + std::vector<uint64_t> m_IncompleteTimes; + + class SequencerWakeupEvent : public Event { private: |