1/** 2 * Copyright (c) 2018 Metempsy Technology Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 24 unchanged lines hidden (view full) --- 33 #include "mem/cache/base.hh" 34 #include "mem/cache/prefetch/associative_set_impl.hh" 35 #include "params/IndirectMemoryPrefetcher.hh" 36 37IndirectMemoryPrefetcher::IndirectMemoryPrefetcher( 38 const IndirectMemoryPrefetcherParams *p) : QueuedPrefetcher(p), 39 maxPrefetchDistance(p->max_prefetch_distance), 40 shiftValues(p->shift_values), prefetchThreshold(p->prefetch_threshold), |
41 streamCounterThreshold(p->stream_counter_threshold), 42 streamingDistance(p->streaming_distance), 43 prefetchTable(p->pt_table_assoc, p->pt_table_entries, |
44 p->pt_table_indexing_policy, p->pt_table_replacement_policy, 45 PrefetchTableEntry(p->num_indirect_counter_bits)), |
46 ipd(p->ipd_table_assoc, p->ipd_table_entries, p->ipd_table_indexing_policy, 47 p->ipd_table_replacement_policy, 48 IndirectPatternDetectorEntry(p->addr_array_len, shiftValues.size())), 49 ipdEntryTrackingMisses(nullptr), 50#if THE_ISA != NULL_ISA 51 byteOrder(TheISA::GuestByteOrder) 52#else 53 byteOrder((ByteOrder) -1) --- 76 unchanged lines hidden (view full) --- 130 // Not enabled (no pattern detected in this stream), 131 // add or update an entry in the pattern detector and 132 // start tracking misses 133 allocateOrUpdateIPDEntry(pt_entry, index); 134 } else if (read_index) { 135 // Enabled entry, update the index 136 pt_entry->index = index; 137 if (!pt_entry->increasedIndirectCounter) { |
138 pt_entry->indirectCounter--; |
139 } else { 140 // Set this to false, to see if the new index 141 // has any match 142 pt_entry->increasedIndirectCounter = false; 143 } 144 145 // If the counter is high enough, start prefetching 146 if (pt_entry->indirectCounter > prefetchThreshold) { |
147 unsigned distance = maxPrefetchDistance * 148 pt_entry->indirectCounter.calcSaturation(); |
149 for (int delta = 1; delta < distance; delta += 1) { 150 Addr pf_addr = pt_entry->baseAddr + 151 (pt_entry->index << pt_entry->shift); 152 addresses.push_back(AddrPriority(pf_addr, 0)); 153 } 154 } 155 } 156 } --- 73 unchanged lines hidden (view full) --- 230 if (ba_array[idx] == (miss_addr - (entry->idx2 << shift))) { 231 // Match found! 232 // Fill the corresponding pt_entry 233 PrefetchTableEntry *pt_entry = 234 (PrefetchTableEntry *) entry->getTag(); 235 pt_entry->baseAddr = ba_array[idx]; 236 pt_entry->shift = shift; 237 pt_entry->enabled = true; |
238 pt_entry->indirectCounter.reset(); |
239 // Release the current IPD Entry 240 entry->reset(); 241 // Do not track more misses 242 ipdEntryTrackingMisses = nullptr; 243 return; 244 } 245 idx += 1; 246 } 247 } 248} 249 250void 251IndirectMemoryPrefetcher::checkAccessMatchOnActiveEntries(Addr addr) 252{ 253 for (auto &pt_entry : prefetchTable) { 254 if (pt_entry.enabled) { 255 if (addr == pt_entry.baseAddr + 256 (pt_entry.index << pt_entry.shift)) { |
257 pt_entry.indirectCounter++; 258 pt_entry.increasedIndirectCounter = true; |
259 } 260 } 261 } 262} 263 264IndirectMemoryPrefetcher* 265IndirectMemoryPrefetcherParams::create() 266{ 267 return new IndirectMemoryPrefetcher(this); 268} |