diff options
-rw-r--r-- | src/mem/cache/prefetch/stride.cc | 55 | ||||
-rw-r--r-- | src/mem/cache/prefetch/stride.hh | 74 |
2 files changed, 87 insertions, 42 deletions
diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc index fde4f3011..c09facef0 100644 --- a/src/mem/cache/prefetch/stride.cc +++ b/src/mem/cache/prefetch/stride.cc @@ -66,28 +66,42 @@ StridePrefetcher::StridePrefetcher(const StridePrefetcherParams *p) 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() @@ -109,8 +123,11 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt, 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 @@ -164,7 +181,7 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt, 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; @@ -174,7 +191,7 @@ StridePrefetcher::calculatePrefetch(const PacketPtr &pkt, } inline Addr -StridePrefetcher::pcHash(Addr pc) const +StridePrefetcher::PCTable::pcHash(Addr pc) const { Addr hash1 = pc >> 1; Addr hash2 = hash1 >> floorLog2(pcTableSets); @@ -182,21 +199,21 @@ StridePrefetcher::pcHash(Addr pc) const } 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 diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh index da3bbb33f..ec22ca63f 100644 --- a/src/mem/cache/prefetch/stride.hh +++ b/src/mem/cache/prefetch/stride.hh @@ -89,44 +89,72 @@ class StridePrefetcher : public QueuedPrefetcher 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, |