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