Fixes to hitLatency, blocking, buffer allocation.

Single-cpu timing mode seems to work now.

--HG--
extra : convert_revision : 720f6172df18a1c941e5bd0e8fdfbd686c13c7ad
This commit is contained in:
Steve Reinhardt
2007-06-22 09:24:07 -07:00
parent eff122797b
commit bdd5fd20fb
6 changed files with 52 additions and 94 deletions

View File

@@ -54,6 +54,7 @@ BaseCache::BaseCache(const std::string &name, Params &params)
writeBuffer(params.numWriteBuffers, params.numMSHRs+1000,
MSHRQueue_WriteBuffer),
blkSize(params.blkSize),
hitLatency(params.hitLatency),
numTarget(params.numTargets),
blocked(0),
noTargetMSHR(NULL),

View File

@@ -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();
}
}

View File

@@ -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.

View File

@@ -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;
}

View File

@@ -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();
}
/**

View File

@@ -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;