BankedCache.patch:

Download Report

Transcript BankedCache.patch:

M5 Multibanked Cache
Jiayuan Meng
[email protected]
Behavior
• A bank accommodates several sets, but a set
cannot spread across several banks
• Requests can be responded in parallel as long
as they are for different banks
• Requests to the same bank are queued and
served in FIFO order
• A new requests are rejected if its
corresponding bank has its queue full.
Parameters
• numBanks: # of banks a cache has
• maxBankPendReqs: # of packets each bank
can queue
• propagateLatency: time to distribute a packet
to a bank
• lookupLatency: time to lookup a block within
a bank
Parameters
The MultiBanks class is a derivative of one of the existing Tag classes:
template <class Repl = LRU>
class MultiBanks : public Repl
{
CacheBank *banks;
// modified interface for latency
modeling
BlkType* findBlock(Addr addr, int
&lat);
// perserved interface
BlkType* findReplacement(Addr addr,
PacketList &writebacks);
BlkType* findBlock(Addr addr) const;
Latency Modeling
MultiBanks<Repl>::findBlock(Addr addr, int &lat)
{
unsigned bank = extractBank(addr);
// calculate the latency that the request reaches the bank
lat = banks[bank].accessBlk(propagateLatency); // see next slide
// adding the latency that the request lookup within the bank
Repl::hitLatency = lat + lookupLatency;
// Repl::findBlock will use existing modules to find the block
// and further adjust the latency according to block.whenReady
BlkType *blk = Repl::findBlock(addr, lat);
return blk;
}
Bank Queuing/pipeline Modeling
int CacheBank::accessBlk(int propagateLatency)
{
// delete requests that are already processed up to now
updateOccupants();
// calculate the time when the request is propagated to the bank
int lat = propagateLatency;
Tick time = curTick + lat;
// take into account the queueing latency
// queueLatency can be less than lookupLatency to model pipelining
int n=occupants.size(); // # of waiting requests for this bank
if(n>0){
// calculate when the incoming request reaches the head of the queue
Tick nextIdle = occupants[n-1]+queueLatency;
if(time < nextIdle){
time = nextIdle;
lat = time - curTick;
}
}
// record this future request’s process time in the occupant list
occupants.push_back(time);
return lat;
}
Bank Conflict
bool Cache<TagStore>::CpuSidePort::recvTiming(PacketPtr pkt)
{
if (pkt->isRequest() && !pkt->memInhibitAsserted() &&
(blocked || !myCache()->accept(pkt) ) )
…(reject the request and retry later)
…
}
Cache::accept(pkt) calls BaseTags::accept(pkt), and if it is a multibanked cache:
MultiBanks<Repl>::accept(Addr addr)
{
unsigned bank = extractBank(addr);
return banks[bank].tryAccept();
}
bool CacheBank::tryAccept()
{
updateOccupants(); // erase requests that are already processed
if( numOccupants()>=maxPendReqs )
return false; // reject if the per-bank queue is full already
return true;
}