From 7b84602b816798b37be666f102f461a9f506a3e6 Mon Sep 17 00:00:00 2001 From: solbjorg <1645846+solbjorg@users.noreply.github.com> Date: Thu, 13 Feb 2020 14:36:06 +0100 Subject: [PATCH] Implemented a basic instruction based strided prefetcher. --- .gitignore | 1 + src/prefetcher.cc | 59 ++++++++++++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/.gitignore b/.gitignore index 40f2379..331f7ce 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ stats.txt build/ output/ +.dir-locals.el diff --git a/src/prefetcher.cc b/src/prefetcher.cc index 58be4e6..33dd8f3 100755 --- a/src/prefetcher.cc +++ b/src/prefetcher.cc @@ -1,36 +1,47 @@ -/* - * A sample prefetcher which does sequential one-block lookahead. - * This means that the prefetcher fetches the next block _after_ the one that - * was just accessed. It also ignores requests to blocks already in the cache. - */ - #include "interface.hh" +#include +typedef struct Stride { + /* list of strides */ + unsigned stride_distance; + unsigned last_addr; + unsigned successive_misses; +} Stride; -void prefetch_init(void) -{ - /* Called before any calls to prefetch_access. */ - /* This is the place to initialize data structures. */ +typedef std::map StrideMap; +static StrideMap stride_map; - //DPRINTF(HWPrefetch, "Initialized sequential-on-access prefetcher\n"); +/* naive stride distance, takes the stride between the previous two */ +void set_stride(Addr mem_addr, Stride *stride) { + stride->stride_distance = mem_addr - stride->last_addr; + stride->last_addr = mem_addr; } -void prefetch_access(AccessStat stat) -{ - /* pf_addr is now an address within the _next_ cache block */ - Addr pf_addr = stat.mem_addr + BLOCK_SIZE; +void prefetch_init(void) { + /* Called before any calls to prefetch_access. */ + /* This is the place to initialize data structures. */ +} - /* - * Issue a prefetch request if a demand miss occured, - * and the block is not already in cache. - */ - if (stat.miss && !in_cache(pf_addr)) { - issue_prefetch(pf_addr); +void prefetch_access(AccessStat stat) { + // never loaded from here before + // check if stride_map[stat.pc] is set. + if (stride_map.find(stat.pc) == stride_map.end()) { + // pf_addr += BLOCK_SIZE; // just load next block, it's a good guess. + // basically means stride of 1. + stride_map[stat.pc].last_addr = stat.mem_addr; + } else { + set_stride(stat.mem_addr, &stride_map[stat.pc]); + DPRINTF(HWPrefetch, "stride distance: %d\n", + stride_map[stat.pc].stride_distance); + Addr pf_addr = stat.mem_addr + stride_map[stat.pc].stride_distance; + if (!in_cache(pf_addr) && pf_addr < MAX_PHYS_MEM_ADDR) { + issue_prefetch(pf_addr); } + } } void prefetch_complete(Addr addr) { - /* - * Called when a block requested by the prefetcher has been loaded. - */ + /* + * Called when a block requested by the prefetcher has been loaded. + */ }