diff options
author | Iru Cai <mytbk920423@gmail.com> | 2019-05-12 14:34:21 +0800 |
---|---|---|
committer | Iru Cai <mytbk920423@gmail.com> | 2019-05-12 14:34:21 +0800 |
commit | b0e609d5cf6961bb9b3f12065659e1c42c13ef06 (patch) | |
tree | d03553831a09a99902b8cf1f631f4e684f433425 /src/mem | |
parent | 2b62fec3590024a7ce82ef5d4647397d37ed37eb (diff) | |
download | gem5-b0e609d5cf6961bb9b3f12065659e1c42c13ef06.tar.xz |
only spec load when hit
Diffstat (limited to 'src/mem')
-rw-r--r-- | src/mem/protocol/MESI_Two_Level-L1cache.sm | 9 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 123 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.hh | 4 |
3 files changed, 16 insertions, 120 deletions
diff --git a/src/mem/protocol/MESI_Two_Level-L1cache.sm b/src/mem/protocol/MESI_Two_Level-L1cache.sm index f5feb7e23..8496fda61 100644 --- a/src/mem/protocol/MESI_Two_Level-L1cache.sm +++ b/src/mem/protocol/MESI_Two_Level-L1cache.sm @@ -981,6 +981,12 @@ machine(MachineType:L1Cache, "MESI Directory L1 Cache CMP") sequencer.readCallback(address, cache_entry.DataBlk); } + action(h_spec_load_miss, "hsm", + desc="Notify sequencer the spec load misses.") + { + sequencer.readCallback(address, cache_entry.DataBlk, true); + } + action(h_ifetch_hit, "hi", desc="Notify sequencer the instruction fetch completed.") { assert(is_valid(cache_entry)); @@ -1222,8 +1228,7 @@ machine(MachineType:L1Cache, "MESI Directory L1 Cache CMP") } transition({NP,I}, SpecLoad, IX) { - iw_allocateTBEWithoutCacheEntry; - as_issueGETSPEC; + h_spec_load_miss; k_popMandatoryQueue; } diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index 4a8e5ae02..090030f08 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -56,9 +56,7 @@ RubySequencerParams::create() Sequencer::Sequencer(const Params *p) : RubyPort(p), m_IncompleteTimes(MachineType_NUM), - deadlockCheckEvent([this]{ wakeup(); }, "Sequencer deadlock check"), - m_specBuf(33), - specBufferHitEvent([this]{ specBufferHitCallback(); }, "Sequencer spec buffer hit") + deadlockCheckEvent([this]{ wakeup(); }, "Sequencer deadlock check") { m_outstanding_count = 0; @@ -429,18 +427,6 @@ Sequencer::writeCallback(Addr address, DataBlock& data, initialRequestTime, forwardRequestTime, firstResponseTime); } -bool Sequencer::updateSBB(PacketPtr pkt, DataBlock& data, Addr dataAddress) { - uint8_t idx = pkt->reqIdx; - SBE& sbe = m_specBuf[idx]; - int blkIdx = pkt->isFirst() ? 0 : 1; - SBB& sbb = sbe.blocks[blkIdx]; - if (makeLineAddress(sbb.reqAddress) == dataAddress) { - sbb.data = data; - return true; - } - return false; -} - // [InvisiSpec] Called by Ruby to send a response to CPU. void Sequencer::readCallback(Addr address, DataBlock& data, @@ -466,71 +452,19 @@ Sequencer::readCallback(Addr address, DataBlock& data, PacketPtr pkt = request->pkt; if (pkt->isSpec()) { - assert(!pkt->onlyAccessSpecBuff()); DPRINTFR(SpecBuffer, "%10s SPEC_LD callback (idx=%d-%d, addr=%#x)\n", curTick(), pkt->reqIdx, pkt->isFirst()? 0 : 1, printAddress(pkt->getAddr())); - updateSBB(pkt, data, address); if (!externalHit) { pkt->setL1Hit(); } - } else if (pkt->isExpose()) { - DPRINTFR(SpecBuffer, "%10s EXPOSE callback (idx=%d-%d, addr=%#x)\n", curTick(), pkt->reqIdx, pkt->isFirst()? 0 : 1, printAddress(pkt->getAddr())); - } else if (pkt->isValidate()) { - DPRINTFR(SpecBuffer, "%10s VALIDATE callback (idx=%d-%d, addr=%#x)\n", curTick(), pkt->reqIdx, pkt->isFirst()? 0 : 1, printAddress(pkt->getAddr())); - uint8_t idx = pkt->reqIdx; - SBE& sbe = m_specBuf[idx]; - int blkIdx = pkt->isFirst() ? 0 : 1; - SBB& sbb = sbe.blocks[blkIdx]; - assert(makeLineAddress(sbb.reqAddress) == address); - if (!memcmp(sbb.data.getData(getOffset(pkt->getAddr()), pkt->getSize()), data.getData(getOffset(pkt->getAddr()), pkt->getSize()), pkt->getSize())) { - *(pkt->getPtr<uint8_t>()) = 1; - } else { - // std::ostringstream os; - // sbb.data.print(os); - // DPRINTFR(SpecBufferValidate, "%s\n", os.str()); - // os.str(""); - // data.print(os); - // DPRINTFR(SpecBufferValidate, "%s\n", os.str()); - *(pkt->getPtr<uint8_t>()) = 0; - } } - for (auto& dependentPkt : request->dependentSpecRequests) { - assert(!dependentPkt->onlyAccessSpecBuff()); - DPRINTFR(SpecBuffer, "%10s Merged SPEC_LD callback (idx=%d-%d, addr=%#x)\n", curTick(), dependentPkt->reqIdx, dependentPkt->isFirst()? 0 : 1, printAddress(dependentPkt->getAddr())); - assert(dependentPkt->isSpec()); - updateSBB(dependentPkt, data, address); - if (!externalHit) { - dependentPkt->setL1Hit(); - } - memcpy(dependentPkt->getPtr<uint8_t>(), - data.getData(getOffset(dependentPkt->getAddr()), dependentPkt->getSize()), - dependentPkt->getSize()); - ruby_hit_callback(dependentPkt); - } + assert(!pkt->isExpose()); + assert(!pkt->isValidate()); hitCallback(request, data, true, mach, externalHit, initialRequestTime, forwardRequestTime, firstResponseTime); } -void -Sequencer::specBufferHitCallback() -{ - assert(m_specRequestQueue.size()); - while (m_specRequestQueue.size()) { - auto specReq = m_specRequestQueue.front(); - if (specReq.second <= curTick()) { - PacketPtr pkt = specReq.first; - assert(pkt->onlyAccessSpecBuff()); - DPRINTFR(SpecBuffer, "%10s SB Hit Callback (idx=%d, addr=%#x)\n", curTick(), pkt->reqIdx, printAddress(pkt->getAddr())); - ruby_hit_callback(pkt); - m_specRequestQueue.pop(); - } else { - schedule(specBufferHitEvent, specReq.second); - break; - } - } -} - // [InvisiSpec] Response on the way from Ruby to CPU void Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data, @@ -567,7 +501,9 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data, data.setData(pkt->getConstPtr<uint8_t>(), getOffset(request_address), pkt->getSize()); } else if (!pkt->isFlush() && !pkt->isExpose() && !pkt->isValidate()) { - if ((type == RubyRequestType_LD) || + if (type == RubyRequestType_SPEC_LD && externalHit) { + DPRINTF(RubySequencer, "spec load miss!\n"); + } else if ((type == RubyRequestType_LD) || (type == RubyRequestType_SPEC_LD) || (type == RubyRequestType_IFETCH) || (type == RubyRequestType_RMW_Read) || @@ -642,51 +578,10 @@ Sequencer::makeRequest(PacketPtr pkt) if (pkt->isSpec()) { assert(pkt->cmd == MemCmd::ReadSpecReq); assert(pkt->isSplit || pkt->isFirst()); - uint8_t idx = pkt->reqIdx; - SBE& sbe = m_specBuf[idx]; - sbe.isSplit = pkt->isSplit; - int blkIdx = pkt->isFirst() ? 0 : 1; - SBB& sbb = sbe.blocks[blkIdx]; - sbb.reqAddress = pkt->getAddr(); - sbb.reqSize = pkt->getSize(); - if (pkt->onlyAccessSpecBuff()) { - int srcIdx = pkt->srcIdx; - SBE& srcEntry = m_specBuf[srcIdx]; - if (makeLineAddress(sbb.reqAddress) == makeLineAddress(srcEntry.blocks[0].reqAddress)) { - sbb.data = srcEntry.blocks[0].data; - } else if (makeLineAddress(sbb.reqAddress) == makeLineAddress(srcEntry.blocks[1].reqAddress)) { - sbb.data = srcEntry.blocks[1].data; - } else { - fatal("Requested address %#x is not present in the spec buffer\n", printAddress(sbb.reqAddress)); - } - memcpy(pkt->getPtr<uint8_t>(), - sbb.data.getData(getOffset(sbb.reqAddress), sbb.reqSize), - sbb.reqSize); - m_specRequestQueue.push({pkt, curTick()}); - DPRINTFR(SpecBuffer, "%10s SB Hit (idx=%d, addr=%#x) on (srcIdx=%d)\n", curTick(), idx, printAddress(sbb.reqAddress), srcIdx); - if (!specBufferHitEvent.scheduled()) { - schedule(specBufferHitEvent, clockEdge(Cycles(1))); - } - return RequestStatus_Issued; - } else { - // assert it is not in the buffer - primary_type = secondary_type = RubyRequestType_SPEC_LD; - } + // assert it is not in the buffer + primary_type = secondary_type = RubyRequestType_SPEC_LD; } else if (pkt->isExpose() || pkt->isValidate()) { - assert(pkt->cmd == MemCmd::ExposeReq || pkt->cmd == MemCmd::ValidateReq); - assert(pkt->isSplit || pkt->isFirst()); - uint8_t idx = pkt->reqIdx; - SBE& sbe = m_specBuf[idx]; - sbe.isSplit = pkt->isSplit; - int blkIdx = pkt->isFirst() ? 0 : 1; - SBB& sbb = sbe.blocks[blkIdx]; - if (sbb.reqAddress != pkt->getAddr()) { - fatal("sbb.reqAddress != pkt->getAddr: %#x != %#x\n", printAddress(sbb.reqAddress), printAddress(pkt->getAddr())); - } - if (sbb.reqSize != pkt->getSize()) { - fatal("sbb.reqSize != pkt->getSize(): %d != %d\n", sbb.reqSize, pkt->getSize()); - } - primary_type = secondary_type = RubyRequestType_EXPOSE; + assert(false); } else if (pkt->isLLSC()) { // // Alpha LL/SC instructions need to be handled carefully by the cache diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index 66ff92777..8e1f08a48 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -256,10 +256,6 @@ class Sequencer : public RubyPort std::vector<Stats::Counter> m_IncompleteTimes; EventFunctionWrapper deadlockCheckEvent; - - std::vector<SBE> m_specBuf; - std::queue<std::pair<PacketPtr, Tick>> m_specRequestQueue; - EventFunctionWrapper specBufferHitEvent; }; inline std::ostream& |