mem: Support any number of master-IDs in stride prefetcher
The stride prefetcher had a hardcoded number of contexts (i.e. master-IDs) that it could handle. Since master IDs need to be unique per system, and every core, cache etc. requires a separate master port, a static limit on these does not make much sense. Instead, this patch adds a small hash map that will map all master IDs to the right prefetch state and dynamically allocates new state for new master IDs.
This commit is contained in:
parent
0197e580e5
commit
cb8856f580
2 changed files with 51 additions and 19 deletions
39
src/mem/cache/prefetch/stride.cc
vendored
39
src/mem/cache/prefetch/stride.cc
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2013 ARM Limited
|
||||
* Copyright (c) 2012-2013, 2015 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
|
@ -59,27 +59,40 @@ StridePrefetcher::StridePrefetcher(const StridePrefetcherParams *p)
|
|||
pcTableAssoc(p->table_assoc),
|
||||
pcTableSets(p->table_sets),
|
||||
useMasterId(p->use_master_id),
|
||||
degree(p->degree)
|
||||
degree(p->degree),
|
||||
pcTable(pcTableAssoc, pcTableSets, name())
|
||||
{
|
||||
// Don't consult stride prefetcher on instruction accesses
|
||||
onInst = false;
|
||||
|
||||
assert(isPowerOf2(pcTableSets));
|
||||
|
||||
for (int c = 0; c < maxContexts; c++) {
|
||||
pcTable[c] = new StrideEntry*[pcTableSets];
|
||||
for (int s = 0; s < pcTableSets; s++) {
|
||||
pcTable[c][s] = new StrideEntry[pcTableAssoc];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StridePrefetcher::~StridePrefetcher()
|
||||
StridePrefetcher::StrideEntry**
|
||||
StridePrefetcher::PCTable::allocateNewContext(int context)
|
||||
{
|
||||
for (int c = 0; c < maxContexts; c++) {
|
||||
auto res = entries.insert(std::make_pair(context,
|
||||
new StrideEntry*[pcTableSets]));
|
||||
auto it = res.first;
|
||||
chatty_assert(res.second, "Allocating an already created context\n");
|
||||
assert(it->first == context);
|
||||
|
||||
DPRINTF(HWPrefetch, "Adding context %i with stride entries at %p\n",
|
||||
context, it->second);
|
||||
|
||||
StrideEntry** entry = it->second;
|
||||
for (int s = 0; s < pcTableSets; s++) {
|
||||
entry[s] = new StrideEntry[pcTableAssoc];
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
StridePrefetcher::PCTable::~PCTable() {
|
||||
for (auto entry : entries) {
|
||||
for (int s = 0; s < pcTableSets; s++) {
|
||||
delete[] pcTable[c][s];
|
||||
delete[] entry.second[s];
|
||||
}
|
||||
delete[] entry.second;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,8 +111,6 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt,
|
|||
bool is_secure = pkt->isSecure();
|
||||
MasterID master_id = useMasterId ? pkt->req->masterId() : 0;
|
||||
|
||||
assert(master_id < maxContexts);
|
||||
|
||||
// Lookup pc-based information
|
||||
StrideEntry *entry;
|
||||
|
||||
|
|
31
src/mem/cache/prefetch/stride.hh
vendored
31
src/mem/cache/prefetch/stride.hh
vendored
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2013 ARM Limited
|
||||
* Copyright (c) 2012-2013, 2015 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
|
@ -48,14 +48,13 @@
|
|||
#ifndef __MEM_CACHE_PREFETCH_STRIDE_HH__
|
||||
#define __MEM_CACHE_PREFETCH_STRIDE_HH__
|
||||
|
||||
#include "base/hashmap.hh"
|
||||
#include "mem/cache/prefetch/queued.hh"
|
||||
#include "params/StridePrefetcher.hh"
|
||||
|
||||
class StridePrefetcher : public QueuedPrefetcher
|
||||
{
|
||||
protected:
|
||||
static const int maxContexts = 64;
|
||||
|
||||
const int maxConf;
|
||||
const int threshConf;
|
||||
const int minConf;
|
||||
|
@ -81,7 +80,30 @@ class StridePrefetcher : public QueuedPrefetcher
|
|||
int confidence;
|
||||
};
|
||||
|
||||
StrideEntry **pcTable[maxContexts];
|
||||
class PCTable
|
||||
{
|
||||
public:
|
||||
PCTable(int assoc, int sets, const std::string name) :
|
||||
pcTableAssoc(assoc), pcTableSets(sets), _name(name) {}
|
||||
StrideEntry** operator[] (int context) {
|
||||
auto it = entries.find(context);
|
||||
if (it != entries.end())
|
||||
return it->second;
|
||||
|
||||
return allocateNewContext(context);
|
||||
}
|
||||
|
||||
~PCTable();
|
||||
private:
|
||||
const std::string name() {return _name; }
|
||||
const int pcTableAssoc;
|
||||
const int pcTableSets;
|
||||
const std::string _name;
|
||||
m5::hash_map<int, StrideEntry**> entries;
|
||||
|
||||
StrideEntry** allocateNewContext(int context);
|
||||
};
|
||||
PCTable pcTable;
|
||||
|
||||
bool pcTableHit(Addr pc, bool is_secure, int master_id, StrideEntry* &entry);
|
||||
StrideEntry* pcTableVictim(Addr pc, int master_id);
|
||||
|
@ -90,7 +112,6 @@ class StridePrefetcher : public QueuedPrefetcher
|
|||
public:
|
||||
|
||||
StridePrefetcher(const StridePrefetcherParams *p);
|
||||
~StridePrefetcher();
|
||||
|
||||
void calculatePrefetch(const PacketPtr &pkt, std::vector<Addr> &addresses);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue