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++) {
}
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;
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();
#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"
private:
/** Prefetcher parameters */
- const int latencyBufferSize;
const int sequentialPrefetchers;
/** Threshold used to issue prefetchers */
* 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;
{}
};
- 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;