pcTableAssoc(p->table_assoc),
pcTableSets(p->table_sets),
useMasterId(p->use_master_id),
- degree(p->degree),
- pcTable(pcTableAssoc, pcTableSets, name())
+ degree(p->degree)
{
assert(isPowerOf2(pcTableSets));
}
-std::vector<std::vector<StridePrefetcher::StrideEntry>>&
-StridePrefetcher::PCTable::allocateNewContext(int context)
+StridePrefetcher::PCTable*
+StridePrefetcher::findTable(int context)
{
- auto res = entries.insert(std::make_pair(context,
- std::vector<std::vector<StrideEntry>>(pcTableSets)));
- auto it = res.first;
- chatty_assert(res.second, "Allocating an already created context\n");
- assert(it->first == context);
+ // Check if table for given context exists
+ auto it = pcTables.find(context);
+ if (it != pcTables.end())
+ return &it->second;
+
+ // If table does not exist yet, create one
+ return allocateNewContext(context);
+}
+
+StridePrefetcher::PCTable*
+StridePrefetcher::allocateNewContext(int context)
+{
+ // Create new table
+ auto insertion_result = pcTables.insert(std::make_pair(context,
+ PCTable(pcTableAssoc, pcTableSets, name())));
DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context);
- std::vector<std::vector<StrideEntry>>& table = it->second;
- for (auto& set : table) {
+ // Get iterator to new pc table, and then return a pointer to the new table
+ return &(insertion_result.first->second);
+}
+
+StridePrefetcher::PCTable::PCTable(int assoc, int sets, const std::string name)
+ : pcTableAssoc(assoc), pcTableSets(sets), _name(name), entries(pcTableSets)
+{
+ for (auto& set : entries) {
set.resize(pcTableAssoc);
}
- return table;
}
StridePrefetcher::PCTable::~PCTable()
bool is_secure = pkt->isSecure();
MasterID master_id = useMasterId ? pkt->req->masterId() : 0;
+ // Get corresponding pc table
+ PCTable* pcTable = findTable(master_id);
+
// Search for entry in the pc table
- StrideEntry *entry = findEntry(pc, is_secure, master_id);
+ StrideEntry *entry = pcTable->findEntry(pc, is_secure);
if (entry != nullptr) {
// Hit in table
DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pkt_addr,
is_secure ? "s" : "ns");
- StrideEntry* entry = pcTableVictim(pc, master_id);
+ StrideEntry* entry = pcTable->findVictim(pc);
entry->instAddr = pc;
entry->lastAddr = pkt_addr;
entry->isSecure= is_secure;
}
inline Addr
-StridePrefetcher::pcHash(Addr pc) const
+StridePrefetcher::PCTable::pcHash(Addr pc) const
{
Addr hash1 = pc >> 1;
Addr hash2 = hash1 >> floorLog2(pcTableSets);
}
inline StridePrefetcher::StrideEntry*
-StridePrefetcher::pcTableVictim(Addr pc, int master_id)
+StridePrefetcher::PCTable::findVictim(Addr pc)
{
// Rand replacement for now
int set = pcHash(pc);
int way = random_mt.random<int>(0, pcTableAssoc - 1);
DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n", set, way);
- return &pcTable[master_id][set][way];
+ return &entries[set][way];
}
inline StridePrefetcher::StrideEntry*
-StridePrefetcher::findEntry(Addr pc, bool is_secure, int master_id)
+StridePrefetcher::PCTable::findEntry(Addr pc, bool is_secure)
{
int set = pcHash(pc);
- std::vector<StrideEntry>& set_entries = pcTable[master_id][set];
+ std::vector<StrideEntry>& set_entries = entries[set];
for (int way = 0; way < pcTableAssoc; way++) {
StrideEntry* entry = &set_entries[way];
// Search ways for match
class PCTable
{
public:
- PCTable(int assoc, int sets, const std::string name) :
- pcTableAssoc(assoc), pcTableSets(sets), _name(name) {}
-
- std::vector<std::vector<StrideEntry>>& operator[] (int context) {
- auto it = entries.find(context);
- if (it != entries.end())
- return it->second;
+ /**
+ * Default constructor. Create a table with given parameters.
+ *
+ * @param assoc Associativity of the table.
+ * @param sets Number of sets in the table.
+ * @param name Name of the prefetcher.
+ */
+ PCTable(int assoc, int sets, const std::string name);
+
+ /**
+ * Default destructor.
+ */
+ ~PCTable();
- return allocateNewContext(context);
- }
+ /**
+ * Search for an entry in the pc table.
+ *
+ * @param pc The PC to look for.
+ * @param is_secure True if the target memory space is secure.
+ * @return Pointer to the entry.
+ */
+ StrideEntry* findEntry(Addr pc, bool is_secure);
+
+ /**
+ * Find a replacement victim to make room for given PC.
+ *
+ * @param pc The PC value.
+ * @return The victimized entry.
+ */
+ StrideEntry* findVictim(Addr pc);
- ~PCTable();
private:
const std::string name() {return _name; }
const int pcTableAssoc;
const int pcTableSets;
const std::string _name;
- std::unordered_map<int, std::vector<std::vector<StrideEntry>>> entries;
-
- std::vector<std::vector<StrideEntry>>& allocateNewContext(int context);
+ std::vector<std::vector<StrideEntry>> entries;
+
+ /**
+ * PC hashing function to index sets in the table.
+ *
+ * @param pc The PC value.
+ * @return The set to which this PC maps.
+ */
+ Addr pcHash(Addr pc) const;
};
- PCTable pcTable;
+ std::unordered_map<int, PCTable> pcTables;
/**
- * Search for an entry in the pc table.
+ * Try to find a table of entries for the given context. If none is
+ * found, a new table is created.
*
- * @param pc The PC to look for.
- * @param is_secure True if the target memory space is secure.
- * @param master_id The context.
- * @return Pointer to the entry.
+ * @param context The context to be searched for.
+ * @return The table corresponding to the given context.
*/
- StrideEntry* findEntry(Addr pc, bool is_secure, int master_id);
+ PCTable* findTable(int context);
- StrideEntry* pcTableVictim(Addr pc, int master_id);
+ /**
+ * Create a PC table for the given context.
+ *
+ * @param context The context of the new PC table.
+ * @return The new PC table
+ */
+ PCTable* allocateNewContext(int context);
- Addr pcHash(Addr pc) const;
public:
-
StridePrefetcher(const StridePrefetcherParams *p);
void calculatePrefetch(const PacketPtr &pkt,