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 <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24541
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Daniel R. Carvalho
2019-12-29 19:09:46 +01:00
committed by Daniel Carvalho
parent feb2042cb1
commit 235f249481
2 changed files with 39 additions and 46 deletions

View File

@@ -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,14 +99,12 @@ SBOOE::notifyFill(const PacketPtr& pkt)
if (it != demandAddresses.end()) {
Tick elapsed_ticks = curTick() - it->second;
if (latencyBuffer.full()) {
latencyBufferSum -= latencyBuffer.front();
}
latencyBuffer.push_back(elapsed_ticks);
latencyBufferSum += elapsed_ticks;
if (latencyBuffer.size() > latencyBufferSize) {
latencyBufferSum -= latencyBuffer.front();
latencyBuffer.pop_front();
}
averageAccessLatency = latencyBufferSum / latencyBuffer.size();
demandAddresses.erase(it);

View File

@@ -35,10 +35,10 @@
#ifndef __MEM_CACHE_PREFETCH_SBOOE_HH__
#define __MEM_CACHE_PREFETCH_SBOOE_HH__
#include <deque>
#include <unordered_map>
#include <vector>
#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<Tick> latencyBuffer;
CircularQueue<Tick> 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<SandboxEntry> entries;
class Sandbox
{
private:
/** FIFO queue containing the sandbox entries. */
CircularQueue<SandboxEntry> 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<Sandbox> sandboxes;
/** Current best sandbox */
Sandbox * bestSandbox;
const Sandbox* bestSandbox;
/** Number of accesses notified to the prefetcher */
unsigned int accesses;