From 235f2494819d7fe6a9d45ce37d6d9e8b1854ede9 Mon Sep 17 00:00:00 2001 From: "Daniel R. Carvalho" Date: Sun, 29 Dec 2019 19:09:46 +0100 Subject: [PATCH] mem-cache: Cleanup of SBOOE prefetcher Made the latencyBuffer a CircularQueue. Improved encapsulation of the Sandbox struct. Fixed score() to follow function declaration guidelines. Removed redundant fatal error checking for score threshold. Change-Id: I1904884e96f103c67930abafc28b75796aadc406 Signed-off-by: Daniel R. Carvalho Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24541 Reviewed-by: Nikos Nikoleris Maintainer: Nikos Nikoleris Tested-by: kokoro --- src/mem/cache/prefetch/sbooe.cc | 51 ++++++++++++++------------------- src/mem/cache/prefetch/sbooe.hh | 34 +++++++++++----------- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/src/mem/cache/prefetch/sbooe.cc b/src/mem/cache/prefetch/sbooe.cc index ecbab686d..2faa1378a 100644 --- a/src/mem/cache/prefetch/sbooe.cc +++ b/src/mem/cache/prefetch/sbooe.cc @@ -35,17 +35,13 @@ namespace Prefetcher { SBOOE::SBOOE(const SBOOEPrefetcherParams *p) : Queued(p), - latencyBufferSize(p->latency_buffer_size), sequentialPrefetchers(p->sequential_prefetchers), scoreThreshold((p->sandbox_entries*p->score_threshold_pct)/100), + latencyBuffer(p->latency_buffer_size), averageAccessLatency(0), latencyBufferSum(0), bestSandbox(NULL), accesses(0) { - if (!(p->score_threshold_pct >= 0 && p->score_threshold_pct <= 100)) { - fatal("%s: the score threshold should be between 0 and 100\n", name()); - } - // Initialize a sandbox for every sequential prefetcher between // -1 and the number of sequential prefetchers defined for (int i = 0; i < sequentialPrefetchers; i++) { @@ -54,34 +50,31 @@ SBOOE::SBOOE(const SBOOEPrefetcherParams *p) } void -SBOOE::Sandbox::insert(Addr addr, Tick tick) +SBOOE::Sandbox::access(Addr addr, Tick tick) { - entries[index].valid = true; - entries[index].line = addr + stride; - entries[index].expectedArrivalTick = tick; - - index++; - - if (index == entries.size()) { - index = 0; + // Search for the address in the FIFO queue to update the score + for (const SandboxEntry &entry: entries) { + if (entry.valid && entry.line == addr) { + sandboxScore++; + if (entry.expectedArrivalTick > curTick()) { + lateScore++; + } + } } + + // Insert new access in this sandbox + SandboxEntry entry; + entry.valid = true; + entry.line = addr + stride; + entry.expectedArrivalTick = tick; + entries.push_back(entry); } bool SBOOE::access(Addr access_line) { for (Sandbox &sb : sandboxes) { - // Search for the address in the FIFO queue - for (const SandboxEntry &entry: sb.entries) { - if (entry.valid && entry.line == access_line) { - sb.sandboxScore++; - if (entry.expectedArrivalTick > curTick()) { - sb.lateScore++; - } - } - } - - sb.insert(access_line, curTick() + averageAccessLatency); + sb.access(access_line, curTick() + averageAccessLatency); if (bestSandbox == NULL || sb.score() > bestSandbox->score()) { bestSandbox = &sb; @@ -106,13 +99,11 @@ SBOOE::notifyFill(const PacketPtr& pkt) if (it != demandAddresses.end()) { Tick elapsed_ticks = curTick() - it->second; - latencyBuffer.push_back(elapsed_ticks); - latencyBufferSum += elapsed_ticks; - - if (latencyBuffer.size() > latencyBufferSize) { + if (latencyBuffer.full()) { latencyBufferSum -= latencyBuffer.front(); - latencyBuffer.pop_front(); } + latencyBuffer.push_back(elapsed_ticks); + latencyBufferSum += elapsed_ticks; averageAccessLatency = latencyBufferSum / latencyBuffer.size(); diff --git a/src/mem/cache/prefetch/sbooe.hh b/src/mem/cache/prefetch/sbooe.hh index 8076732b9..42deaf387 100644 --- a/src/mem/cache/prefetch/sbooe.hh +++ b/src/mem/cache/prefetch/sbooe.hh @@ -35,10 +35,10 @@ #ifndef __MEM_CACHE_PREFETCH_SBOOE_HH__ #define __MEM_CACHE_PREFETCH_SBOOE_HH__ -#include #include #include +#include "base/circular_queue.hh" #include "mem/cache/prefetch/queued.hh" #include "mem/packet.hh" @@ -51,7 +51,6 @@ class SBOOE : public Queued private: /** Prefetcher parameters */ - const int latencyBufferSize; const int sequentialPrefetchers; /** Threshold used to issue prefetchers */ @@ -70,7 +69,7 @@ class SBOOE : public Queued * calculate the average access latency which is later used to * predict if a prefetcher would be filled on time if issued. */ - std::deque latencyBuffer; + CircularQueue latencyBuffer; /** Holds the current average access latency */ Tick averageAccessLatency; @@ -91,48 +90,51 @@ class SBOOE : public Queued {} }; - struct Sandbox { - /** FIFO queue. Max entries is 'sandboxEntries' */ - std::vector entries; + class Sandbox + { + private: + /** FIFO queue containing the sandbox entries. */ + CircularQueue entries; + /** * Accesses during the eval period that were present * in the sandbox */ unsigned int sandboxScore; + /** Hits in the sandbox that wouldn't have been filled on time */ unsigned int lateScore; - /** Index of the oldest entry in the FIFO */ - unsigned int index; + + public: /** Sequential stride for this prefetcher */ const int stride; Sandbox(unsigned int max_entries, int _stride) - : sandboxScore(0), lateScore(0), index(0), stride(_stride) + : entries(max_entries), sandboxScore(0), lateScore(0), + stride(_stride) { - entries.resize(max_entries); } /** - * Insert the line address being accessed to the cache into the + * Update score and insert the line address being accessed into the * FIFO queue of the sandbox. + * * @param line Line address being accessed * @param tick Tick in which the access is expected to be filled */ - void insert(Addr line, Tick tick); + void access(Addr line, Tick tick); /** Calculate the useful score * @return Useful score of the sandbox. Sandbox score adjusted by * by the late score */ - unsigned int score() const { - return (sandboxScore - lateScore); - } + unsigned int score() const { return (sandboxScore - lateScore); } }; std::vector sandboxes; /** Current best sandbox */ - Sandbox * bestSandbox; + const Sandbox* bestSandbox; /** Number of accesses notified to the prefetcher */ unsigned int accesses; -- 2.30.2