From cb8856f58059df962652243a9a9c7549571d79fa Mon Sep 17 00:00:00 2001 From: Stephan Diestelhorst Date: Fri, 27 Mar 2015 04:56:03 -0400 Subject: [PATCH] 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. --- src/mem/cache/prefetch/stride.cc | 37 +++++++++++++++++++++----------- src/mem/cache/prefetch/stride.hh | 31 +++++++++++++++++++++----- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc index 74c84b94f..bcd72f25a 100644 --- a/src/mem/cache/prefetch/stride.cc +++ b/src/mem/cache/prefetch/stride.cc @@ -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::StrideEntry** +StridePrefetcher::PCTable::allocateNewContext(int context) +{ + 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::~StridePrefetcher() -{ - for (int c = 0; c < maxContexts; c++) { +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; diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh index 7d8f12110..2798c823f 100644 --- a/src/mem/cache/prefetch/stride.hh +++ b/src/mem/cache/prefetch/stride.hh @@ -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 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 &addresses); }; -- 2.30.2