From: Steve Reinhardt Date: Fri, 22 Jun 2007 16:24:07 +0000 (-0700) Subject: Fixes to hitLatency, blocking, buffer allocation. X-Git-Tag: m5_2.0_beta4~195^2~50^2~40 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bdd5fd20fb19eb52ef812cd284094e5513646e36;p=gem5.git Fixes to hitLatency, blocking, buffer allocation. Single-cpu timing mode seems to work now. --HG-- extra : convert_revision : 720f6172df18a1c941e5bd0e8fdfbd686c13c7ad --- diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc index 8b476e100..1f5182574 100644 --- a/src/mem/cache/base_cache.cc +++ b/src/mem/cache/base_cache.cc @@ -54,6 +54,7 @@ BaseCache::BaseCache(const std::string &name, Params ¶ms) writeBuffer(params.numWriteBuffers, params.numMSHRs+1000, MSHRQueue_WriteBuffer), blkSize(params.blkSize), + hitLatency(params.hitLatency), numTarget(params.numTargets), blocked(0), noTargetMSHR(NULL), diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh index 10fd3289c..27134b2ad 100644 --- a/src/mem/cache/base_cache.hh +++ b/src/mem/cache/base_cache.hh @@ -195,6 +195,11 @@ class BaseCache : public MemObject /** Block size of this cache */ const int blkSize; + /** + * The latency of a hit in this device. + */ + int hitLatency; + /** The number of targets for each MSHR. */ const int numTarget; @@ -464,15 +469,10 @@ class BaseCache : public MemObject if (blocked == 0) { blocked_causes[cause]++; blockedCycle = curTick; + cpuSidePort->setBlocked(); } - int old_state = blocked; - if (!(blocked & flag)) { - //Wasn't already blocked for this cause - blocked |= flag; - DPRINTF(Cache,"Blocking for cause %s\n", cause); - if (!old_state) - cpuSidePort->setBlocked(); - } + blocked |= flag; + DPRINTF(Cache,"Blocking for cause %d, mask=%d\n", cause, blocked); } /** @@ -485,16 +485,11 @@ class BaseCache : public MemObject void clearBlocked(BlockedCause cause) { uint8_t flag = 1 << cause; - DPRINTF(Cache,"Unblocking for cause %s, causes left=%i\n", - cause, blocked); - if (blocked & flag) - { - blocked &= ~flag; - if (!isBlocked()) { - blocked_cycles[cause] += curTick - blockedCycle; - DPRINTF(Cache,"Unblocking from all causes\n"); - cpuSidePort->clearBlocked(); - } + blocked &= ~flag; + DPRINTF(Cache,"Unblocking for cause %d, mask=%d\n", cause, blocked); + if (blocked == 0) { + blocked_cycles[cause] += curTick - blockedCycle; + cpuSidePort->clearBlocked(); } } diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh index 06fce1a71..a93b761ec 100644 --- a/src/mem/cache/cache.hh +++ b/src/mem/cache/cache.hh @@ -136,23 +136,6 @@ class Cache : public BaseCache /** Prefetcher */ BasePrefetcher *prefetcher; - /** - * The clock ratio of the outgoing bus. - * Used for calculating critical word first. - */ - int busRatio; - - /** - * The bus width in bytes of the outgoing bus. - * Used for calculating critical word first. - */ - int busWidth; - - /** - * The latency of a hit in this device. - */ - int hitLatency; - /** * Can this cache should allocate a block on a line-sized write miss. */ @@ -303,15 +286,6 @@ class Cache : public BaseCache */ void squash(int threadNum); - /** - * Allocate a new MSHR or write buffer to handle a miss. - * @param pkt The access that missed. - * @param time The time to continue processing the miss. - * @param isFill Whether to fetch & allocate a block - * or just forward the request. - */ - MSHR *allocateBuffer(PacketPtr pkt, Tick time, bool requestBus); - /** * Selects a outstanding request to service. * @return The request to service, NULL if none found. diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh index 81fcb4158..0649b5061 100644 --- a/src/mem/cache/cache_impl.hh +++ b/src/mem/cache/cache_impl.hh @@ -149,27 +149,6 @@ Cache::cmpAndSwap(BlkType *blk, PacketPtr pkt) ///////////////////////////////////////////////////// -template -MSHR * -Cache::allocateBuffer(PacketPtr pkt, Tick time, - bool requestBus) -{ - MSHRQueue *mq = NULL; - - if (pkt->isWrite() && !pkt->isRead()) { - /** - * @todo Add write merging here. - */ - mq = &writeBuffer; - } else { - mq = &mshrQueue; - } - - return allocateBufferInternal(mq, pkt->getAddr(), pkt->getSize(), - pkt, time, requestBus); -} - - template void Cache::markInService(MSHR *mshr) @@ -438,6 +417,8 @@ Cache::getBusPacket(PacketPtr cpu_pkt, BlkType *blk, return NULL; } + assert(cpu_pkt->needsResponse()); + MemCmd cmd; const bool useUpgrades = true; if (blkValid && useUpgrades) { @@ -1043,23 +1024,34 @@ Cache::getTimingPacket() return NULL; } - BlkType *blk = tags->findBlock(mshr->addr); - // use request from 1st target PacketPtr tgt_pkt = mshr->getTarget()->pkt; - PacketPtr pkt = getBusPacket(tgt_pkt, blk, mshr->needsExclusive); + PacketPtr pkt = NULL; - mshr->isCacheFill = (pkt != NULL); - - if (pkt == NULL) { - // make copy of current packet to forward - pkt = new Packet(tgt_pkt); - pkt->allocate(); - if (pkt->isWrite()) { - pkt->setData(tgt_pkt->getPtr()); + if (mshr->isSimpleForward()) { + // no response expected, just forward packet as it is + assert(tags->findBlock(mshr->addr) == NULL); + pkt = tgt_pkt; + } else { + BlkType *blk = tags->findBlock(mshr->addr); + pkt = getBusPacket(tgt_pkt, blk, mshr->needsExclusive); + + mshr->isCacheFill = (pkt != NULL); + + if (pkt == NULL) { + // not a cache block request, but a response is expected + assert(!mshr->isSimpleForward()); + // make copy of current packet to forward, keep current + // copy for response handling + pkt = new Packet(tgt_pkt); + pkt->allocate(); + if (pkt->isWrite()) { + pkt->setData(tgt_pkt->getPtr()); + } } } + assert(pkt != NULL); pkt->senderState = mshr; return pkt; } diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh index 47f6a819b..195438e46 100644 --- a/src/mem/cache/miss/mshr.hh +++ b/src/mem/cache/miss/mshr.hh @@ -164,28 +164,19 @@ public: * Returns the current number of allocated targets. * @return The current number of allocated targets. */ - int getNumTargets() - { - return ntargets; - } + int getNumTargets() { return ntargets; } /** * Returns a pointer to the target list. * @return a pointer to the target list. */ - TargetList* getTargetList() - { - return &targets; - } + TargetList* getTargetList() { return &targets; } /** * Returns a reference to the first target. * @return A pointer to the first target. */ - Target *getTarget() - { - return &targets.front(); - } + Target *getTarget() { return &targets.front(); } /** * Pop first target. @@ -200,9 +191,14 @@ public: * Returns true if there are targets left. * @return true if there are targets */ - bool hasTargets() + bool hasTargets() { return !targets.empty(); } + + bool isSimpleForward() { - return !targets.empty(); + if (getNumTargets() != 1) + return false; + Target *tgt = getTarget(); + return tgt->isCpuSide() && !tgt->pkt->needsResponse(); } /** diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc index 6b030a865..3407e2588 100644 --- a/src/mem/cache/miss/mshr_queue.cc +++ b/src/mem/cache/miss/mshr_queue.cc @@ -158,14 +158,14 @@ MSHRQueue::moveToFront(MSHR *mshr) void MSHRQueue::markInService(MSHR *mshr) { - //assert(mshr == pendingList.front()); -#if 0 - if (!mshr->pkt->needsResponse() && !(mshr->pkt->cmd == MemCmd::UpgradeReq)) { - assert(mshr->getNumTargets() == 0); + if (mshr->isSimpleForward()) { + // we just forwarded the request packet & don't expect a + // response, so get rid of it + assert(mshr->getNumTargets() == 1); + mshr->popTarget(); deallocate(mshr); return; } -#endif mshr->inService = true; pendingList.erase(mshr->readyIter); //mshr->readyIter = NULL;