Fixes to hitLatency, blocking, buffer allocation.
Single-cpu timing mode seems to work now. --HG-- extra : convert_revision : 720f6172df18a1c941e5bd0e8fdfbd686c13c7ad
This commit is contained in:
1
src/mem/cache/base_cache.cc
vendored
1
src/mem/cache/base_cache.cc
vendored
@@ -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),
|
||||
|
||||
31
src/mem/cache/base_cache.hh
vendored
31
src/mem/cache/base_cache.hh
vendored
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
26
src/mem/cache/cache.hh
vendored
26
src/mem/cache/cache.hh
vendored
@@ -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.
|
||||
|
||||
54
src/mem/cache/cache_impl.hh
vendored
54
src/mem/cache/cache_impl.hh
vendored
@@ -149,27 +149,6 @@ Cache<TagStore,Coherence>::cmpAndSwap(BlkType *blk, PacketPtr pkt)
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
|
||||
template<class TagStore, class Coherence>
|
||||
MSHR *
|
||||
Cache<TagStore,Coherence>::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<class TagStore, class Coherence>
|
||||
void
|
||||
Cache<TagStore,Coherence>::markInService(MSHR *mshr)
|
||||
@@ -438,6 +417,8 @@ Cache<TagStore,Coherence>::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<TagStore,Coherence>::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 (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);
|
||||
|
||||
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<uint8_t>());
|
||||
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<uint8_t>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(pkt != NULL);
|
||||
pkt->senderState = mshr;
|
||||
return pkt;
|
||||
}
|
||||
|
||||
24
src/mem/cache/miss/mshr.hh
vendored
24
src/mem/cache/miss/mshr.hh
vendored
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
10
src/mem/cache/miss/mshr_queue.cc
vendored
10
src/mem/cache/miss/mshr_queue.cc
vendored
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user