113735Sivan.pizarro@metempsy.com/**
213735Sivan.pizarro@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting
313735Sivan.pizarro@metempsy.com * All rights reserved.
413735Sivan.pizarro@metempsy.com *
513735Sivan.pizarro@metempsy.com * Redistribution and use in source and binary forms, with or without
613735Sivan.pizarro@metempsy.com * modification, are permitted provided that the following conditions are
713735Sivan.pizarro@metempsy.com * met: redistributions of source code must retain the above copyright
813735Sivan.pizarro@metempsy.com * notice, this list of conditions and the following disclaimer;
913735Sivan.pizarro@metempsy.com * redistributions in binary form must reproduce the above copyright
1013735Sivan.pizarro@metempsy.com * notice, this list of conditions and the following disclaimer in the
1113735Sivan.pizarro@metempsy.com * documentation and/or other materials provided with the distribution;
1213735Sivan.pizarro@metempsy.com * neither the name of the copyright holders nor the names of its
1313735Sivan.pizarro@metempsy.com * contributors may be used to endorse or promote products derived from
1413735Sivan.pizarro@metempsy.com * this software without specific prior written permission.
1513735Sivan.pizarro@metempsy.com *
1613735Sivan.pizarro@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1713735Sivan.pizarro@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1813735Sivan.pizarro@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1913735Sivan.pizarro@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2013735Sivan.pizarro@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2113735Sivan.pizarro@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2213735Sivan.pizarro@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2313735Sivan.pizarro@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2413735Sivan.pizarro@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2513735Sivan.pizarro@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2613735Sivan.pizarro@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2713735Sivan.pizarro@metempsy.com *
2813735Sivan.pizarro@metempsy.com * Authors: Ivan Pizarro
2913735Sivan.pizarro@metempsy.com */
3013735Sivan.pizarro@metempsy.com
3113735Sivan.pizarro@metempsy.com#include "mem/cache/prefetch/sbooe.hh"
3213735Sivan.pizarro@metempsy.com
3313735Sivan.pizarro@metempsy.com#include "debug/HWPrefetch.hh"
3413735Sivan.pizarro@metempsy.com#include "params/SBOOEPrefetcher.hh"
3513735Sivan.pizarro@metempsy.com
3613735Sivan.pizarro@metempsy.comSBOOEPrefetcher::SBOOEPrefetcher(const SBOOEPrefetcherParams *p)
3713735Sivan.pizarro@metempsy.com    : QueuedPrefetcher(p),
3813735Sivan.pizarro@metempsy.com      latencyBufferSize(p->latency_buffer_size),
3913735Sivan.pizarro@metempsy.com      sequentialPrefetchers(p->sequential_prefetchers),
4013735Sivan.pizarro@metempsy.com      scoreThreshold((p->sandbox_entries*p->score_threshold_pct)/100),
4113735Sivan.pizarro@metempsy.com      averageAccessLatency(0), latencyBufferSum(0),
4213735Sivan.pizarro@metempsy.com      bestSandbox(NULL),
4313735Sivan.pizarro@metempsy.com      accesses(0)
4413735Sivan.pizarro@metempsy.com{
4513735Sivan.pizarro@metempsy.com    if (!(p->score_threshold_pct >= 0 && p->score_threshold_pct <= 100)) {
4613735Sivan.pizarro@metempsy.com        fatal("%s: the score threshold should be between 0 and 100\n", name());
4713735Sivan.pizarro@metempsy.com    }
4813735Sivan.pizarro@metempsy.com
4913735Sivan.pizarro@metempsy.com    // Initialize a sandbox for every sequential prefetcher between
5013735Sivan.pizarro@metempsy.com    // -1 and the number of sequential prefetchers defined
5113735Sivan.pizarro@metempsy.com    for (int i = 0; i < sequentialPrefetchers; i++) {
5213735Sivan.pizarro@metempsy.com        sandboxes.push_back(Sandbox(p->sandbox_entries, i-1));
5313735Sivan.pizarro@metempsy.com    }
5413735Sivan.pizarro@metempsy.com}
5513735Sivan.pizarro@metempsy.com
5613735Sivan.pizarro@metempsy.comvoid
5713735Sivan.pizarro@metempsy.comSBOOEPrefetcher::Sandbox::insert(Addr addr, Tick tick)
5813735Sivan.pizarro@metempsy.com{
5913735Sivan.pizarro@metempsy.com    entries[index].valid = true;
6013735Sivan.pizarro@metempsy.com    entries[index].line = addr + stride;
6113735Sivan.pizarro@metempsy.com    entries[index].expectedArrivalTick = tick;
6213735Sivan.pizarro@metempsy.com
6313735Sivan.pizarro@metempsy.com    index++;
6413735Sivan.pizarro@metempsy.com
6513735Sivan.pizarro@metempsy.com    if (index == entries.size()) {
6613735Sivan.pizarro@metempsy.com        index = 0;
6713735Sivan.pizarro@metempsy.com    }
6813735Sivan.pizarro@metempsy.com}
6913735Sivan.pizarro@metempsy.com
7013735Sivan.pizarro@metempsy.combool
7113735Sivan.pizarro@metempsy.comSBOOEPrefetcher::access(Addr access_line)
7213735Sivan.pizarro@metempsy.com{
7313735Sivan.pizarro@metempsy.com    for (Sandbox &sb : sandboxes) {
7413735Sivan.pizarro@metempsy.com        // Search for the address in the FIFO queue
7513735Sivan.pizarro@metempsy.com        for (const SandboxEntry &entry: sb.entries) {
7613735Sivan.pizarro@metempsy.com            if (entry.valid && entry.line == access_line) {
7713735Sivan.pizarro@metempsy.com                sb.sandboxScore++;
7813735Sivan.pizarro@metempsy.com                if (entry.expectedArrivalTick > curTick()) {
7913735Sivan.pizarro@metempsy.com                    sb.lateScore++;
8013735Sivan.pizarro@metempsy.com                }
8113735Sivan.pizarro@metempsy.com            }
8213735Sivan.pizarro@metempsy.com        }
8313735Sivan.pizarro@metempsy.com
8413735Sivan.pizarro@metempsy.com        sb.insert(access_line, curTick() + averageAccessLatency);
8513735Sivan.pizarro@metempsy.com
8613735Sivan.pizarro@metempsy.com        if (bestSandbox == NULL || sb.score() > bestSandbox->score()) {
8713735Sivan.pizarro@metempsy.com            bestSandbox = &sb;
8813735Sivan.pizarro@metempsy.com        }
8913735Sivan.pizarro@metempsy.com    }
9013735Sivan.pizarro@metempsy.com
9113735Sivan.pizarro@metempsy.com    accesses++;
9213735Sivan.pizarro@metempsy.com
9313735Sivan.pizarro@metempsy.com    return (accesses >= sandboxes.size());
9413735Sivan.pizarro@metempsy.com}
9513735Sivan.pizarro@metempsy.com
9613735Sivan.pizarro@metempsy.comvoid
9713735Sivan.pizarro@metempsy.comSBOOEPrefetcher::notifyFill(const PacketPtr& pkt)
9813735Sivan.pizarro@metempsy.com{
9913735Sivan.pizarro@metempsy.com    // (1) Look for the address in the demands list
10013735Sivan.pizarro@metempsy.com    // (2) Calculate the elapsed cycles until it was filled (curTick)
10113735Sivan.pizarro@metempsy.com    // (3) Insert the latency into the latency buffer (FIFO)
10213735Sivan.pizarro@metempsy.com    // (4) Calculate the new average access latency
10313735Sivan.pizarro@metempsy.com
10413735Sivan.pizarro@metempsy.com    auto it = demandAddresses.find(pkt->getAddr());
10513735Sivan.pizarro@metempsy.com
10613735Sivan.pizarro@metempsy.com    if (it != demandAddresses.end()) {
10713735Sivan.pizarro@metempsy.com        Tick elapsed_ticks = curTick() - it->second;
10813735Sivan.pizarro@metempsy.com
10913735Sivan.pizarro@metempsy.com        latencyBuffer.push_back(elapsed_ticks);
11013735Sivan.pizarro@metempsy.com        latencyBufferSum += elapsed_ticks;
11113735Sivan.pizarro@metempsy.com
11213735Sivan.pizarro@metempsy.com        if (latencyBuffer.size() > latencyBufferSize) {
11313735Sivan.pizarro@metempsy.com            latencyBufferSum -= latencyBuffer.front();
11413735Sivan.pizarro@metempsy.com            latencyBuffer.pop_front();
11513735Sivan.pizarro@metempsy.com        }
11613735Sivan.pizarro@metempsy.com
11713735Sivan.pizarro@metempsy.com        averageAccessLatency = latencyBufferSum / latencyBuffer.size();
11813735Sivan.pizarro@metempsy.com
11913735Sivan.pizarro@metempsy.com        demandAddresses.erase(it);
12013735Sivan.pizarro@metempsy.com    }
12113735Sivan.pizarro@metempsy.com}
12213735Sivan.pizarro@metempsy.com
12313735Sivan.pizarro@metempsy.comvoid
12413735Sivan.pizarro@metempsy.comSBOOEPrefetcher::calculatePrefetch(const PrefetchInfo &pfi,
12513735Sivan.pizarro@metempsy.com                                   std::vector<AddrPriority> &addresses)
12613735Sivan.pizarro@metempsy.com{
12713735Sivan.pizarro@metempsy.com    const Addr pfi_addr = pfi.getAddr();
12813735Sivan.pizarro@metempsy.com    const Addr pfi_line = pfi_addr >> lBlkSize;
12913735Sivan.pizarro@metempsy.com
13013735Sivan.pizarro@metempsy.com    auto it = demandAddresses.find(pfi_addr);
13113735Sivan.pizarro@metempsy.com
13213735Sivan.pizarro@metempsy.com    if (it == demandAddresses.end()) {
13313735Sivan.pizarro@metempsy.com        demandAddresses.insert(std::pair<Addr, Tick>(pfi_addr, curTick()));
13413735Sivan.pizarro@metempsy.com    }
13513735Sivan.pizarro@metempsy.com
13613735Sivan.pizarro@metempsy.com    const bool evaluationFinished = access(pfi_line);
13713735Sivan.pizarro@metempsy.com
13813735Sivan.pizarro@metempsy.com    if (evaluationFinished && bestSandbox->score() > scoreThreshold) {
13913735Sivan.pizarro@metempsy.com        Addr pref_line = pfi_line + bestSandbox->stride;
14013735Sivan.pizarro@metempsy.com        addresses.push_back(AddrPriority(pref_line << lBlkSize, 0));
14113735Sivan.pizarro@metempsy.com    }
14213735Sivan.pizarro@metempsy.com}
14313735Sivan.pizarro@metempsy.com
14413735Sivan.pizarro@metempsy.comSBOOEPrefetcher*
14513735Sivan.pizarro@metempsy.comSBOOEPrefetcherParams::create()
14613735Sivan.pizarro@metempsy.com{
14713735Sivan.pizarro@metempsy.com    return new SBOOEPrefetcher(this);
14813735Sivan.pizarro@metempsy.com}
149