diff options
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: |