stride.cc (13426:d2b0e9ec67f1) | stride.cc (13427:72a3afac3e78) |
---|---|
1/* | 1/* |
2 * Copyright (c) 2018 Inria |
|
2 * Copyright (c) 2012-2013, 2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license --- 24 unchanged lines hidden (view full) --- 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Ron Dreslinski 41 * Steve Reinhardt | 3 * Copyright (c) 2012-2013, 2015 ARM Limited 4 * All rights reserved 5 * 6 * The license below extends only to copyright in the software and shall 7 * not be construed as granting a license to any other intellectual 8 * property including but not limited to intellectual property relating 9 * to a hardware implementation of the functionality of the software 10 * licensed hereunder. You may use the software subject to the license --- 24 unchanged lines hidden (view full) --- 35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Authors: Ron Dreslinski 42 * Steve Reinhardt |
43 * Daniel Carvalho |
|
42 */ 43 44/** 45 * @file 46 * Stride Prefetcher template instantiations. 47 */ 48 49#include "mem/cache/prefetch/stride.hh" 50 51#include <cassert> 52 53#include "base/intmath.hh" 54#include "base/logging.hh" 55#include "base/random.hh" 56#include "base/trace.hh" 57#include "debug/HWPrefetch.hh" | 44 */ 45 46/** 47 * @file 48 * Stride Prefetcher template instantiations. 49 */ 50 51#include "mem/cache/prefetch/stride.hh" 52 53#include <cassert> 54 55#include "base/intmath.hh" 56#include "base/logging.hh" 57#include "base/random.hh" 58#include "base/trace.hh" 59#include "debug/HWPrefetch.hh" |
60#include "mem/cache/replacement_policies/base.hh" |
|
58#include "params/StridePrefetcher.hh" 59 60StridePrefetcher::StrideEntry::StrideEntry() 61{ 62 invalidate(); 63} 64 65void --- 10 unchanged lines hidden (view full) --- 76 : QueuedPrefetcher(p), 77 maxConf(p->max_conf), 78 threshConf(p->thresh_conf), 79 minConf(p->min_conf), 80 startConf(p->start_conf), 81 pcTableAssoc(p->table_assoc), 82 pcTableSets(p->table_sets), 83 useMasterId(p->use_master_id), | 61#include "params/StridePrefetcher.hh" 62 63StridePrefetcher::StrideEntry::StrideEntry() 64{ 65 invalidate(); 66} 67 68void --- 10 unchanged lines hidden (view full) --- 79 : QueuedPrefetcher(p), 80 maxConf(p->max_conf), 81 threshConf(p->thresh_conf), 82 minConf(p->min_conf), 83 startConf(p->start_conf), 84 pcTableAssoc(p->table_assoc), 85 pcTableSets(p->table_sets), 86 useMasterId(p->use_master_id), |
84 degree(p->degree) | 87 degree(p->degree), 88 replacementPolicy(p->replacement_policy) |
85{ 86 assert(isPowerOf2(pcTableSets)); 87} 88 89StridePrefetcher::PCTable* 90StridePrefetcher::findTable(int context) 91{ 92 // Check if table for given context exists --- 5 unchanged lines hidden (view full) --- 98 return allocateNewContext(context); 99} 100 101StridePrefetcher::PCTable* 102StridePrefetcher::allocateNewContext(int context) 103{ 104 // Create new table 105 auto insertion_result = pcTables.insert(std::make_pair(context, | 89{ 90 assert(isPowerOf2(pcTableSets)); 91} 92 93StridePrefetcher::PCTable* 94StridePrefetcher::findTable(int context) 95{ 96 // Check if table for given context exists --- 5 unchanged lines hidden (view full) --- 102 return allocateNewContext(context); 103} 104 105StridePrefetcher::PCTable* 106StridePrefetcher::allocateNewContext(int context) 107{ 108 // Create new table 109 auto insertion_result = pcTables.insert(std::make_pair(context, |
106 PCTable(pcTableAssoc, pcTableSets, name()))); | 110 PCTable(pcTableAssoc, pcTableSets, name(), replacementPolicy))); |
107 108 DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context); 109 110 // Get iterator to new pc table, and then return a pointer to the new table 111 return &(insertion_result.first->second); 112} 113 | 111 112 DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context); 113 114 // Get iterator to new pc table, and then return a pointer to the new table 115 return &(insertion_result.first->second); 116} 117 |
114StridePrefetcher::PCTable::PCTable(int assoc, int sets, const std::string name) 115 : pcTableAssoc(assoc), pcTableSets(sets), _name(name), entries(pcTableSets) | 118StridePrefetcher::PCTable::PCTable(int assoc, int sets, const std::string name, 119 BaseReplacementPolicy* replacementPolicy) 120 : pcTableSets(sets), _name(name), entries(pcTableSets), 121 replacementPolicy(replacementPolicy) |
116{ | 122{ |
117 for (auto& set : entries) { 118 set.resize(pcTableAssoc); | 123 for (int set = 0; set < sets; set++) { 124 entries[set].resize(assoc); 125 for (int way = 0; way < assoc; way++) { 126 // Inform the entry its position 127 entries[set][way].setPosition(set, way); 128 129 // Initialize replacement policy data 130 entries[set][way].replacementData = 131 replacementPolicy->instantiateEntry(); 132 } |
119 } 120} 121 122StridePrefetcher::PCTable::~PCTable() 123{ 124} 125 126void --- 68 unchanged lines hidden (view full) --- 195 // Miss in table 196 DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pkt_addr, 197 is_secure ? "s" : "ns"); 198 199 StrideEntry* entry = pcTable->findVictim(pc); 200 201 // Invalidate victim 202 entry->invalidate(); | 133 } 134} 135 136StridePrefetcher::PCTable::~PCTable() 137{ 138} 139 140void --- 68 unchanged lines hidden (view full) --- 209 // Miss in table 210 DPRINTF(HWPrefetch, "Miss: PC %x pkt_addr %x (%s)\n", pc, pkt_addr, 211 is_secure ? "s" : "ns"); 212 213 StrideEntry* entry = pcTable->findVictim(pc); 214 215 // Invalidate victim 216 entry->invalidate(); |
217 replacementPolicy->invalidate(entry->replacementData); |
|
203 204 // Insert new entry's data 205 entry->instAddr = pc; 206 entry->lastAddr = pkt_addr; | 218 219 // Insert new entry's data 220 entry->instAddr = pc; 221 entry->lastAddr = pkt_addr; |
207 entry->isSecure= is_secure; | 222 entry->isSecure = is_secure; |
208 entry->confidence = startConf; | 223 entry->confidence = startConf; |
224 replacementPolicy->reset(entry->replacementData); |
|
209 } 210} 211 212inline Addr 213StridePrefetcher::PCTable::pcHash(Addr pc) const 214{ 215 Addr hash1 = pc >> 1; 216 Addr hash2 = hash1 >> floorLog2(pcTableSets); 217 return (hash1 ^ hash2) & (Addr)(pcTableSets - 1); 218} 219 220inline StridePrefetcher::StrideEntry* 221StridePrefetcher::PCTable::findVictim(Addr pc) 222{ 223 // Rand replacement for now 224 int set = pcHash(pc); | 225 } 226} 227 228inline Addr 229StridePrefetcher::PCTable::pcHash(Addr pc) const 230{ 231 Addr hash1 = pc >> 1; 232 Addr hash2 = hash1 >> floorLog2(pcTableSets); 233 return (hash1 ^ hash2) & (Addr)(pcTableSets - 1); 234} 235 236inline StridePrefetcher::StrideEntry* 237StridePrefetcher::PCTable::findVictim(Addr pc) 238{ 239 // Rand replacement for now 240 int set = pcHash(pc); |
225 int way = random_mt.random<int>(0, pcTableAssoc - 1); | |
226 | 241 |
227 DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n", set, way); 228 return &entries[set][way]; | 242 // Get possible entries to be victimized 243 std::vector<ReplaceableEntry*> possible_entries; 244 for (auto& entry : entries[set]) { 245 possible_entries.push_back(&entry); 246 } 247 248 // Choose victim based on replacement policy 249 StrideEntry* victim = static_cast<StrideEntry*>( 250 replacementPolicy->getVictim(possible_entries)); 251 252 DPRINTF(HWPrefetch, "Victimizing lookup table[%d][%d].\n", 253 victim->getSet(), victim->getWay()); 254 255 return victim; |
229} 230 231inline StridePrefetcher::StrideEntry* 232StridePrefetcher::PCTable::findEntry(Addr pc, bool is_secure) 233{ 234 int set = pcHash(pc); | 256} 257 258inline StridePrefetcher::StrideEntry* 259StridePrefetcher::PCTable::findEntry(Addr pc, bool is_secure) 260{ 261 int set = pcHash(pc); |
235 std::vector<StrideEntry>& set_entries = entries[set]; 236 for (int way = 0; way < pcTableAssoc; way++) { 237 StrideEntry* entry = &set_entries[way]; | 262 for (auto& entry : entries[set]) { |
238 // Search ways for match | 263 // Search ways for match |
239 if ((entry->instAddr == pc) && (entry->isSecure == is_secure)) { 240 DPRINTF(HWPrefetch, "Lookup hit table[%d][%d].\n", set, way); 241 return entry; | 264 if ((entry.instAddr == pc) && (entry.isSecure == is_secure)) { 265 DPRINTF(HWPrefetch, "Lookup hit table[%d][%d].\n", entry.getSet(), 266 entry.getWay()); 267 replacementPolicy->touch(entry.replacementData); 268 return &entry; |
242 } 243 } 244 return nullptr; 245} 246 247StridePrefetcher* 248StridePrefetcherParams::create() 249{ 250 return new StridePrefetcher(this); 251} | 269 } 270 } 271 return nullptr; 272} 273 274StridePrefetcher* 275StridePrefetcherParams::create() 276{ 277 return new StridePrefetcher(this); 278} |