From: Daniel Date: Sun, 11 Nov 2018 15:11:40 +0000 (+0100) Subject: mem-cache: Make PCTable context independent X-Git-Tag: v19.0.0.0~1394 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2b619afba17e8aaac90d105e691bd901aff10994;p=gem5.git mem-cache: Make PCTable context independent Move the unordered_map outside of the PCTable, as it belongs to the StridePrefetcher. By doing so we are moving towards a table that ressembles the ones of the Tags classes. Some functions have been moved from the prefetcher to the PCTable, as they didn't belong there. As such, they have been renamed to remove the unnecessary prefix. Change-Id: I3e54bc7dee65e1f78d96b0d548ac8345b7bd4364 Signed-off-by: Daniel Reviewed-on: https://gem5-review.googlesource.com/c/14358 Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris --- 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>& -StridePrefetcher::PCTable::allocateNewContext(int context) +StridePrefetcher::PCTable* +StridePrefetcher::findTable(int context) { - auto res = entries.insert(std::make_pair(context, - std::vector>(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>& 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(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& set_entries = pcTable[master_id][set]; + std::vector& 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>& 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>> entries; - - std::vector>& allocateNewContext(int context); + std::vector> 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 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,