mem: Add parameter to reserve MSHR entries for demand access

Adds a new parameter that reserves some number of MSHR entries for demand
accesses.  This helps prevent prefetchers from taking all MSHRs, forcing demand
requests from the CPU to stall.
This commit is contained in:
Mitch Hayenga
2014-12-23 09:31:18 -05:00
parent 4d88978913
commit 6cb58b2bd2
5 changed files with 27 additions and 7 deletions

View File

@@ -54,6 +54,7 @@ class BaseCache(MemObject):
max_miss_count = Param.Counter(0,
"number of misses to handle before calling exit")
mshrs = Param.Int("number of MSHRs (max outstanding requests)")
demand_mshr_reserve = Param.Int(1, "mshrs to reserve for demand access")
size = Param.MemorySize("capacity in bytes")
forward_snoops = Param.Bool(True,
"forward snoops from mem side to cpu side")

View File

@@ -68,8 +68,8 @@ BaseCache::CacheSlavePort::CacheSlavePort(const std::string &_name,
BaseCache::BaseCache(const Params *p)
: MemObject(p),
cpuSidePort(nullptr), memSidePort(nullptr),
mshrQueue("MSHRs", p->mshrs, 4, MSHRQueue_MSHRs),
writeBuffer("write buffer", p->write_buffers, p->mshrs+1000,
mshrQueue("MSHRs", p->mshrs, 4, p->demand_mshr_reserve, MSHRQueue_MSHRs),
writeBuffer("write buffer", p->write_buffers, p->mshrs+1000, 0,
MSHRQueue_WriteBuffer),
blkSize(p->system->cacheLineSize()),
hitLatency(p->hit_latency),

View File

@@ -1841,7 +1841,7 @@ Cache<TagStore>::getNextMSHR()
// fall through... no pending requests. Try a prefetch.
assert(!miss_mshr && !write_mshr);
if (prefetcher && !mshrQueue.isFull()) {
if (prefetcher && mshrQueue.canPrefetch()) {
// If we have a miss queue slot, we can try a prefetch
PacketPtr pkt = prefetcher->getPacket();
if (pkt) {

View File

@@ -52,10 +52,12 @@
using namespace std;
MSHRQueue::MSHRQueue(const std::string &_label,
int num_entries, int reserve, int _index)
int num_entries, int reserve, int demand_reserve,
int _index)
: label(_label), numEntries(num_entries + reserve - 1),
numReserve(reserve), registers(numEntries),
drainManager(NULL), allocated(0), inServiceEntries(0), index(_index)
numReserve(reserve), demandReserve(demand_reserve),
registers(numEntries), drainManager(NULL), allocated(0),
inServiceEntries(0), index(_index)
{
for (int i = 0; i < numEntries; ++i) {
registers[i].queue = this;

View File

@@ -77,6 +77,12 @@ class MSHRQueue : public Drainable
*/
const int numReserve;
/**
* The number of entries to reserve for future demand accesses.
* Prevent prefetcher from taking all mshr entries
*/
const int demandReserve;
/** MSHR storage. */
std::vector<MSHR> registers;
/** Holds pointers to all allocated entries. */
@@ -106,9 +112,11 @@ class MSHRQueue : public Drainable
* @param num_entrys The number of entries in this queue.
* @param reserve The minimum number of entries needed to satisfy
* any access.
* @param demand_reserve The minimum number of entries needed to satisfy
* demand accesses.
*/
MSHRQueue(const std::string &_label, int num_entries, int reserve,
int index);
int demand_reserve, int index);
/**
* Find the first MSHR that matches the provided address.
@@ -217,6 +225,15 @@ class MSHRQueue : public Drainable
return (allocated > numEntries - numReserve);
}
/**
* Returns true if sufficient mshrs for prefetch.
* @return True if sufficient mshrs for prefetch.
*/
bool canPrefetch() const
{
return (allocated < numEntries - (numReserve + demandReserve));
}
/**
* Returns the MSHR at the head of the readyList.
* @return The next request to service.