base.cc revision 5875:d82be3235ab4
12131SN/A/* 25268Sksewell@umich.edu * Copyright (c) 2005 The Regents of The University of Michigan 35254Sksewell@umich.edu * All rights reserved. 45254Sksewell@umich.edu * 52131SN/A * Redistribution and use in source and binary forms, with or without 65254Sksewell@umich.edu * modification, are permitted provided that the following conditions are 75254Sksewell@umich.edu * met: redistributions of source code must retain the above copyright 85254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer; 95254Sksewell@umich.edu * redistributions in binary form must reproduce the above copyright 105254Sksewell@umich.edu * notice, this list of conditions and the following disclaimer in the 115254Sksewell@umich.edu * documentation and/or other materials provided with the distribution; 125254Sksewell@umich.edu * neither the name of the copyright holders nor the names of its 135254Sksewell@umich.edu * contributors may be used to endorse or promote products derived from 145254Sksewell@umich.edu * this software without specific prior written permission. 155254Sksewell@umich.edu * 162131SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175254Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185254Sksewell@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195254Sksewell@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205254Sksewell@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215254Sksewell@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225254Sksewell@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235254Sksewell@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245254Sksewell@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255254Sksewell@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265254Sksewell@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275254Sksewell@umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski 295254Sksewell@umich.edu */ 305254Sksewell@umich.edu 315222Sksewell@umich.edu/** 322131SN/A * @file 332131SN/A * Hardware Prefetcher Definition. 342239SN/A */ 352680Sktlim@umich.edu 362447SN/A#include "arch/isa_traits.hh" 372447SN/A#include "base/trace.hh" 385222Sksewell@umich.edu#include "mem/cache/base.hh" 392800Ssaidi@eecs.umich.edu#include "mem/cache/prefetch/base.hh" 402800Ssaidi@eecs.umich.edu#include "mem/request.hh" 412800Ssaidi@eecs.umich.edu#include <list> 422800Ssaidi@eecs.umich.edu 432131SN/ABasePrefetcher::BasePrefetcher(const BaseCacheParams *p) 442447SN/A : size(p->prefetcher_size), pageStop(!p->prefetch_past_page), 452447SN/A serialSquash(p->prefetch_serial_squash), 462131SN/A cacheCheckPush(p->prefetch_cache_check_push), 472479SN/A onlyData(p->prefetch_data_accesses_only) 482447SN/A{ 492447SN/A} 502131SN/A 512479SN/Avoid 522447SN/ABasePrefetcher::setCache(BaseCache *_cache) 532447SN/A{ 542447SN/A cache = _cache; 555224Sksewell@umich.edu blkSize = cache->getBlockSize(); 565222Sksewell@umich.edu _name = cache->name() + "-pf"; 575222Sksewell@umich.edu} 585222Sksewell@umich.edu 595222Sksewell@umich.eduvoid 605222Sksewell@umich.eduBasePrefetcher::regStats(const std::string &name) 612447SN/A{ 622447SN/A pfIdentified 635222Sksewell@umich.edu .name(name + ".prefetcher.num_hwpf_identified") 645222Sksewell@umich.edu .desc("number of hwpf identified") 655222Sksewell@umich.edu ; 665222Sksewell@umich.edu 675222Sksewell@umich.edu pfMSHRHit 685222Sksewell@umich.edu .name(name + ".prefetcher.num_hwpf_already_in_mshr") 695222Sksewell@umich.edu .desc("number of hwpf that were already in mshr") 705222Sksewell@umich.edu ; 715222Sksewell@umich.edu 725222Sksewell@umich.edu pfCacheHit 735222Sksewell@umich.edu .name(name + ".prefetcher.num_hwpf_already_in_cache") 745222Sksewell@umich.edu .desc("number of hwpf that were already in the cache") 755222Sksewell@umich.edu ; 765224Sksewell@umich.edu 775222Sksewell@umich.edu pfBufferHit 784661Sksewell@umich.edu .name(name + ".prefetcher.num_hwpf_already_in_prefetcher") 794661Sksewell@umich.edu .desc("number of hwpf that were already in the prefetch queue") 805224Sksewell@umich.edu ; 815222Sksewell@umich.edu 824661Sksewell@umich.edu pfRemovedFull 834661Sksewell@umich.edu .name(name + ".prefetcher.num_hwpf_evicted") 845224Sksewell@umich.edu .desc("number of hwpf removed due to no buffer left") 854661Sksewell@umich.edu ; 864661Sksewell@umich.edu 874661Sksewell@umich.edu pfRemovedMSHR 885222Sksewell@umich.edu .name(name + ".prefetcher.num_hwpf_removed_MSHR_hit") 895222Sksewell@umich.edu .desc("number of hwpf removed because MSHR allocated") 902447SN/A ; 912447SN/A 924661Sksewell@umich.edu pfIssued 934661Sksewell@umich.edu .name(name + ".prefetcher.num_hwpf_issued") 944661Sksewell@umich.edu .desc("number of hwpf issued") 954661Sksewell@umich.edu ; 962447SN/A 975222Sksewell@umich.edu pfSpanPage 982447SN/A .name(name + ".prefetcher.num_hwpf_span_page") 992447SN/A .desc("number of hwpf spanning a virtual page") 1005222Sksewell@umich.edu ; 1015222Sksewell@umich.edu 1025222Sksewell@umich.edu pfSquashed 1035222Sksewell@umich.edu .name(name + ".prefetcher.num_hwpf_squashed_from_miss") 1045222Sksewell@umich.edu .desc("number of hwpf that got squashed due to a miss " 1055222Sksewell@umich.edu "aborting calculation time") 1065222Sksewell@umich.edu ; 1075222Sksewell@umich.edu} 1085222Sksewell@umich.edu 1095222Sksewell@umich.eduinline bool 1105222Sksewell@umich.eduBasePrefetcher::inCache(Addr addr) 1115222Sksewell@umich.edu{ 1125222Sksewell@umich.edu if (cache->inCache(addr)) { 1135222Sksewell@umich.edu pfCacheHit++; 1145222Sksewell@umich.edu return true; 1155222Sksewell@umich.edu } 1165222Sksewell@umich.edu return false; 1175222Sksewell@umich.edu} 1185222Sksewell@umich.edu 1195222Sksewell@umich.eduinline bool 1205222Sksewell@umich.eduBasePrefetcher::inMissQueue(Addr addr) 1215222Sksewell@umich.edu{ 1225222Sksewell@umich.edu if (cache->inMissQueue(addr)) { 1235222Sksewell@umich.edu pfMSHRHit++; 1245222Sksewell@umich.edu return true; 1255222Sksewell@umich.edu } 1265222Sksewell@umich.edu return false; 1275222Sksewell@umich.edu} 1282447SN/A 1292447SN/APacketPtr 1302447SN/ABasePrefetcher::getPacket() 1312447SN/A{ 1322447SN/A DPRINTF(HWPrefetch, "Requesting a hw_pf to issue\n"); 1332447SN/A 1342447SN/A if (pf.empty()) { 1352447SN/A DPRINTF(HWPrefetch, "No HW_PF found\n"); 1362447SN/A return NULL; 1372447SN/A } 1382447SN/A 1392447SN/A PacketPtr pkt; 1402447SN/A bool keep_trying = false; 1412447SN/A do { 1422447SN/A pkt = *pf.begin(); 1432447SN/A pf.pop_front(); 1445222Sksewell@umich.edu if (!cacheCheckPush) { 1455222Sksewell@umich.edu keep_trying = cache->inCache(pkt->getAddr()); 1465222Sksewell@umich.edu } 1472447SN/A 1485222Sksewell@umich.edu if (keep_trying) { 1495222Sksewell@umich.edu DPRINTF(HWPrefetch, "addr 0x%x in cache, skipping\n", 1505222Sksewell@umich.edu pkt->getAddr()); 1512447SN/A delete pkt->req; 1525222Sksewell@umich.edu delete pkt; 1535222Sksewell@umich.edu } 1545222Sksewell@umich.edu 1552447SN/A if (pf.empty()) { 1565222Sksewell@umich.edu cache->deassertMemSideBusRequest(BaseCache::Request_PF); 1572447SN/A if (keep_trying) { 1582447SN/A return NULL; // None left, all were in cache 1592447SN/A } 1605222Sksewell@umich.edu } 1612447SN/A } while (keep_trying); 1622447SN/A 1632447SN/A pfIssued++; 1645222Sksewell@umich.edu assert(pkt != NULL); 1654661Sksewell@umich.edu DPRINTF(HWPrefetch, "returning 0x%x\n", pkt->getAddr()); 1664661Sksewell@umich.edu return pkt; 1674661Sksewell@umich.edu} 1685222Sksewell@umich.edu 1696378Sgblack@eecs.umich.edu 1706378Sgblack@eecs.umich.eduTick 1715222Sksewell@umich.eduBasePrefetcher::notify(PacketPtr &pkt, Tick time) 1726378Sgblack@eecs.umich.edu{ 1736378Sgblack@eecs.umich.edu if (!pkt->req->isUncacheable() && !(pkt->req->isInstRead() && onlyData)) { 1746378Sgblack@eecs.umich.edu // Calculate the blk address 1755222Sksewell@umich.edu Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1); 1765222Sksewell@umich.edu 1776378Sgblack@eecs.umich.edu // Check if miss is in pfq, if so remove it 1786379Sgblack@eecs.umich.edu std::list<PacketPtr>::iterator iter = inPrefetch(blk_addr); 1795222Sksewell@umich.edu if (iter != pf.end()) { 1806378Sgblack@eecs.umich.edu DPRINTF(HWPrefetch, "Saw a miss to a queued prefetch addr: " 1816379Sgblack@eecs.umich.edu "0x%x, removing it\n", blk_addr); 1826379Sgblack@eecs.umich.edu pfRemovedMSHR++; 1836378Sgblack@eecs.umich.edu delete (*iter)->req; 1846379Sgblack@eecs.umich.edu delete (*iter); 1856379Sgblack@eecs.umich.edu pf.erase(iter); 1866379Sgblack@eecs.umich.edu if (pf.empty()) 1876379Sgblack@eecs.umich.edu cache->deassertMemSideBusRequest(BaseCache::Request_PF); 1885222Sksewell@umich.edu } 1895222Sksewell@umich.edu 1906378Sgblack@eecs.umich.edu // Remove anything in queue with delay older than time 1916379Sgblack@eecs.umich.edu // since everything is inserted in time order, start from end 1926379Sgblack@eecs.umich.edu // and work until pf.empty() or time is earlier 1935222Sksewell@umich.edu // This is done to emulate Aborting the previous work on a new miss 1946378Sgblack@eecs.umich.edu // Needed for serial calculators like GHB 1956378Sgblack@eecs.umich.edu if (serialSquash) { 1966378Sgblack@eecs.umich.edu iter = pf.end(); 1976378Sgblack@eecs.umich.edu iter--; 1986378Sgblack@eecs.umich.edu while (!pf.empty() && ((*iter)->time >= time)) { 1996379Sgblack@eecs.umich.edu pfSquashed++; 2006378Sgblack@eecs.umich.edu DPRINTF(HWPrefetch, "Squashing old prefetch addr: 0x%x\n", 2016379Sgblack@eecs.umich.edu (*iter)->getAddr()); 2026378Sgblack@eecs.umich.edu delete (*iter)->req; 2036379Sgblack@eecs.umich.edu delete (*iter); 2046378Sgblack@eecs.umich.edu pf.erase(iter); 2056379Sgblack@eecs.umich.edu iter--; 2066378Sgblack@eecs.umich.edu } 2076379Sgblack@eecs.umich.edu if (pf.empty()) 2086378Sgblack@eecs.umich.edu cache->deassertMemSideBusRequest(BaseCache::Request_PF); 2095222Sksewell@umich.edu } 2106378Sgblack@eecs.umich.edu 2116379Sgblack@eecs.umich.edu 2126379Sgblack@eecs.umich.edu std::list<Addr> addresses; 2136379Sgblack@eecs.umich.edu std::list<Tick> delays; 2146379Sgblack@eecs.umich.edu calculatePrefetch(pkt, addresses, delays); 2156379Sgblack@eecs.umich.edu 2166378Sgblack@eecs.umich.edu std::list<Addr>::iterator addrIter = addresses.begin(); 2176378Sgblack@eecs.umich.edu std::list<Tick>::iterator delayIter = delays.begin(); 2186378Sgblack@eecs.umich.edu for (; addrIter != addresses.end(); ++addrIter, ++delayIter) { 2196378Sgblack@eecs.umich.edu Addr addr = *addrIter; 2206378Sgblack@eecs.umich.edu 2216378Sgblack@eecs.umich.edu pfIdentified++; 2226378Sgblack@eecs.umich.edu 2236378Sgblack@eecs.umich.edu DPRINTF(HWPrefetch, "Found a pf candidate addr: 0x%x, " 2246378Sgblack@eecs.umich.edu "inserting into prefetch queue with delay %d time %d\n", 2256378Sgblack@eecs.umich.edu addr, *delayIter, time); 2266379Sgblack@eecs.umich.edu 2276378Sgblack@eecs.umich.edu // Check if it is already in the cache 2286378Sgblack@eecs.umich.edu if (cacheCheckPush && cache->inCache(addr)) { 2296379Sgblack@eecs.umich.edu DPRINTF(HWPrefetch, "Prefetch addr already in cache\n"); 2306378Sgblack@eecs.umich.edu continue; 2316379Sgblack@eecs.umich.edu } 2326378Sgblack@eecs.umich.edu 2336378Sgblack@eecs.umich.edu // Check if it is already in the miss_queue 2346378Sgblack@eecs.umich.edu if (cache->inMissQueue(addr)) { 2356378Sgblack@eecs.umich.edu DPRINTF(HWPrefetch, "Prefetch addr already in miss queue\n"); 2366378Sgblack@eecs.umich.edu continue; 2376378Sgblack@eecs.umich.edu } 2386378Sgblack@eecs.umich.edu 2396378Sgblack@eecs.umich.edu // Check if it is already in the pf buffer 2406378Sgblack@eecs.umich.edu if (inPrefetch(addr) != pf.end()) { 2416378Sgblack@eecs.umich.edu pfBufferHit++; 2426378Sgblack@eecs.umich.edu DPRINTF(HWPrefetch, "Prefetch addr already in pf buffer\n"); 2436379Sgblack@eecs.umich.edu continue; 2446378Sgblack@eecs.umich.edu } 2456378Sgblack@eecs.umich.edu 2466378Sgblack@eecs.umich.edu // create a prefetch memreq 2476378Sgblack@eecs.umich.edu Request *prefetchReq = new Request(*addrIter, blkSize, 0); 2486379Sgblack@eecs.umich.edu PacketPtr prefetch = 2496378Sgblack@eecs.umich.edu new Packet(prefetchReq, MemCmd::HardPFReq, Packet::Broadcast); 2506378Sgblack@eecs.umich.edu prefetch->allocate(); 2516378Sgblack@eecs.umich.edu prefetch->req->setThreadContext(pkt->req->contextId(), 2526378Sgblack@eecs.umich.edu pkt->req->threadId()); 2536378Sgblack@eecs.umich.edu 2546378Sgblack@eecs.umich.edu prefetch->time = time + (*delayIter); // @todo ADD LATENCY HERE 2556378Sgblack@eecs.umich.edu 2566378Sgblack@eecs.umich.edu // We just remove the head if we are full 2576378Sgblack@eecs.umich.edu if (pf.size() == size) { 2586378Sgblack@eecs.umich.edu pfRemovedFull++; 2596378Sgblack@eecs.umich.edu PacketPtr old_pkt = *pf.begin(); 2606378Sgblack@eecs.umich.edu DPRINTF(HWPrefetch, "Prefetch queue full, " 2616379Sgblack@eecs.umich.edu "removing oldest 0x%x\n", old_pkt->getAddr()); 2626378Sgblack@eecs.umich.edu delete old_pkt->req; 2636378Sgblack@eecs.umich.edu delete old_pkt; 2646378Sgblack@eecs.umich.edu pf.pop_front(); 2656378Sgblack@eecs.umich.edu } 2666378Sgblack@eecs.umich.edu 2676378Sgblack@eecs.umich.edu pf.push_back(prefetch); 2686378Sgblack@eecs.umich.edu } 2696378Sgblack@eecs.umich.edu } 2706378Sgblack@eecs.umich.edu 2716378Sgblack@eecs.umich.edu return pf.empty() ? 0 : pf.front()->time; 2726378Sgblack@eecs.umich.edu} 2736379Sgblack@eecs.umich.edu 2746378Sgblack@eecs.umich.edustd::list<PacketPtr>::iterator 2756378Sgblack@eecs.umich.eduBasePrefetcher::inPrefetch(Addr address) 2766378Sgblack@eecs.umich.edu{ 2776378Sgblack@eecs.umich.edu // Guaranteed to only be one match, we always check before inserting 2786378Sgblack@eecs.umich.edu std::list<PacketPtr>::iterator iter; 2796378Sgblack@eecs.umich.edu for (iter = pf.begin(); iter != pf.end(); iter++) { 2806378Sgblack@eecs.umich.edu if (((*iter)->getAddr() & ~(Addr)(blkSize-1)) == address) { 2816378Sgblack@eecs.umich.edu return iter; 2826379Sgblack@eecs.umich.edu } 2836379Sgblack@eecs.umich.edu } 2846379Sgblack@eecs.umich.edu return pf.end(); 2856379Sgblack@eecs.umich.edu} 2866379Sgblack@eecs.umich.edu 2876379Sgblack@eecs.umich.edubool 2886379Sgblack@eecs.umich.eduBasePrefetcher::samePage(Addr a, Addr b) 2896379Sgblack@eecs.umich.edu{ 2906379Sgblack@eecs.umich.edu return roundDown(a, TheISA::VMPageSize) == roundDown(b, TheISA::VMPageSize); 2916379Sgblack@eecs.umich.edu} 2926378Sgblack@eecs.umich.edu