base.cc revision 4022
1360SN/A/*
21458SN/A * Copyright (c) 2005 The Regents of The University of Michigan
3360SN/A * All rights reserved.
4360SN/A *
5360SN/A * Redistribution and use in source and binary forms, with or without
6360SN/A * modification, are permitted provided that the following conditions are
7360SN/A * met: redistributions of source code must retain the above copyright
8360SN/A * notice, this list of conditions and the following disclaimer;
9360SN/A * redistributions in binary form must reproduce the above copyright
10360SN/A * notice, this list of conditions and the following disclaimer in the
11360SN/A * documentation and/or other materials provided with the distribution;
12360SN/A * neither the name of the copyright holders nor the names of its
13360SN/A * contributors may be used to endorse or promote products derived from
14360SN/A * this software without specific prior written permission.
15360SN/A *
16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Ron Dreslinski
292665Ssaidi@eecs.umich.edu */
30360SN/A
31360SN/A/**
321354SN/A * @file
331354SN/A * Hardware Prefetcher Definition.
34360SN/A */
352764Sstever@eecs.umich.edu
362764Sstever@eecs.umich.edu#include "base/trace.hh"
372064SN/A#include "mem/cache/base_cache.hh"
38360SN/A#include "mem/cache/prefetch/base_prefetcher.hh"
39360SN/A#include "mem/request.hh"
40360SN/A#include <list>
41360SN/A
42360SN/ABasePrefetcher::BasePrefetcher(int size, bool pageStop, bool serialSquash,
43360SN/A                               bool cacheCheckPush, bool onlyData)
441809SN/A    :size(size), pageStop(pageStop), serialSquash(serialSquash),
455543Ssaidi@eecs.umich.edu     cacheCheckPush(cacheCheckPush), only_data(onlyData)
461809SN/A{
473113Sgblack@eecs.umich.edu}
488229Snate@binkert.org
498229Snate@binkert.orgvoid
503113Sgblack@eecs.umich.eduBasePrefetcher::setCache(BaseCache *_cache)
517075Snate@binkert.org{
528229Snate@binkert.org    cache = _cache;
537075Snate@binkert.org    blkSize = cache->getBlockSize();
54360SN/A}
552474SN/A
565543Ssaidi@eecs.umich.eduvoid
572462SN/ABasePrefetcher::regStats(const std::string &name)
581354SN/A{
596216Snate@binkert.org    pfIdentified
606658Snate@binkert.org        .name(name + ".prefetcher.num_hwpf_identified")
612474SN/A        .desc("number of hwpf identified")
622680Sktlim@umich.edu        ;
638229Snate@binkert.org
642474SN/A    pfMSHRHit
657678Sgblack@eecs.umich.edu        .name(name + ".prefetcher.num_hwpf_already_in_mshr")
668229Snate@binkert.org        .desc("number of hwpf that were already in mshr")
676640Svince@csl.cornell.edu        ;
68360SN/A
69360SN/A    pfCacheHit
70360SN/A        .name(name + ".prefetcher.num_hwpf_already_in_cache")
71360SN/A        .desc("number of hwpf that were already in the cache")
72360SN/A        ;
73360SN/A
74360SN/A    pfBufferHit
75360SN/A        .name(name + ".prefetcher.num_hwpf_already_in_prefetcher")
76378SN/A        .desc("number of hwpf that were already in the prefetch queue")
771450SN/A        ;
783114Sgblack@eecs.umich.edu
79360SN/A    pfRemovedFull
805543Ssaidi@eecs.umich.edu        .name(name + ".prefetcher.num_hwpf_evicted")
815543Ssaidi@eecs.umich.edu        .desc("number of hwpf removed due to no buffer left")
825543Ssaidi@eecs.umich.edu        ;
83360SN/A
84360SN/A    pfRemovedMSHR
85360SN/A        .name(name + ".prefetcher.num_hwpf_removed_MSHR_hit")
86360SN/A        .desc("number of hwpf removed because MSHR allocated")
87360SN/A        ;
882680Sktlim@umich.edu
89360SN/A    pfIssued
90360SN/A        .name(name + ".prefetcher.num_hwpf_issued")
91360SN/A        .desc("number of hwpf issued")
92360SN/A        ;
93360SN/A
94360SN/A    pfSpanPage
95360SN/A        .name(name + ".prefetcher.num_hwpf_span_page")
96360SN/A        .desc("number of hwpf spanning a virtual page")
97360SN/A        ;
98360SN/A
99360SN/A    pfSquashed
1003114Sgblack@eecs.umich.edu        .name(name + ".prefetcher.num_hwpf_squashed_from_miss")
101360SN/A        .desc("number of hwpf that got squashed due to a miss aborting calculation time")
102360SN/A        ;
103360SN/A}
104360SN/A
105360SN/Ainline bool
106360SN/ABasePrefetcher::inCache(Addr addr)
107360SN/A{
108360SN/A    if (cache->inCache(addr)) {
109360SN/A        pfCacheHit++;
110360SN/A        return true;
111360SN/A    }
112360SN/A    return false;
113360SN/A}
114360SN/A
115360SN/Ainline bool
116360SN/ABasePrefetcher::inMissQueue(Addr addr)
117360SN/A{
118360SN/A    if (cache->inMissQueue(addr)) {
119360SN/A        pfMSHRHit++;
120360SN/A        return true;
121360SN/A    }
1222400SN/A    return false;
123360SN/A}
1242461SN/A
1255543Ssaidi@eecs.umich.eduPacketPtr
126360SN/ABasePrefetcher::getPacket()
127360SN/A{
128360SN/A    DPRINTF(HWPrefetch, "%s:Requesting a hw_pf to issue\n", cache->name());
129360SN/A
130360SN/A    if (pf.empty()) {
1312400SN/A        DPRINTF(HWPrefetch, "%s:No HW_PF found\n", cache->name());
132360SN/A        return NULL;
1332461SN/A    }
1345543Ssaidi@eecs.umich.edu
135360SN/A    PacketPtr pkt;
136360SN/A    bool keepTrying = false;
137360SN/A    do {
138360SN/A        pkt = *pf.begin();
139360SN/A        pf.pop_front();
140360SN/A        if (!cacheCheckPush) {
141360SN/A            keepTrying = cache->inCache(pkt->getAddr());
142360SN/A        }
143360SN/A        if (pf.empty()) {
144360SN/A            cache->clearMasterRequest(Request_PF);
145360SN/A            if (keepTrying) return NULL; //None left, all were in cache
146360SN/A        }
147360SN/A    } while (keepTrying);
1485543Ssaidi@eecs.umich.edu
149360SN/A    pfIssued++;
150360SN/A    return pkt;
151360SN/A}
152360SN/A
153360SN/Avoid
154360SN/ABasePrefetcher::handleMiss(PacketPtr &pkt, Tick time)
155360SN/A{
156360SN/A    if (!pkt->req->isUncacheable() && !(pkt->req->isInstRead() && only_data))
157360SN/A    {
158360SN/A        //Calculate the blk address
159360SN/A        Addr blkAddr = pkt->getAddr() & ~(Addr)(blkSize-1);
160360SN/A
161360SN/A        //Check if miss is in pfq, if so remove it
162360SN/A        std::list<PacketPtr>::iterator iter = inPrefetch(blkAddr);
163360SN/A        if (iter != pf.end()) {
164360SN/A            DPRINTF(HWPrefetch, "%s:Saw a miss to a queued prefetch, removing it\n", cache->name());
165360SN/A            pfRemovedMSHR++;
1665543Ssaidi@eecs.umich.edu            pf.erase(iter);
1675543Ssaidi@eecs.umich.edu            if (pf.empty())
168502SN/A                cache->clearMasterRequest(Request_PF);
169360SN/A        }
170360SN/A
171360SN/A        //Remove anything in queue with delay older than time
172360SN/A        //since everything is inserted in time order, start from end
173360SN/A        //and work until pf.empty() or time is earlier
174360SN/A        //This is done to emulate Aborting the previous work on a new miss
175360SN/A        //Needed for serial calculators like GHB
176360SN/A        if (serialSquash) {
177360SN/A            iter = pf.end();
178360SN/A            iter--;
179360SN/A            while (!pf.empty() && ((*iter)->time >= time)) {
180378SN/A                pfSquashed++;
1811706SN/A                pf.pop_back();
1823114Sgblack@eecs.umich.edu                iter--;
183378SN/A            }
184378SN/A            if (pf.empty())
185378SN/A                cache->clearMasterRequest(Request_PF);
186378SN/A        }
187378SN/A
1881706SN/A
1893114Sgblack@eecs.umich.edu        std::list<Addr> addresses;
1908149SChris.Emmons@ARM.com        std::list<Tick> delays;
1918149SChris.Emmons@ARM.com        calculatePrefetch(pkt, addresses, delays);
192360SN/A
1936109Ssanchezd@stanford.edu        std::list<Addr>::iterator addr = addresses.begin();
1941706SN/A        std::list<Tick>::iterator delay = delays.begin();
1953114Sgblack@eecs.umich.edu        while (addr != addresses.end())
196378SN/A        {
1976109Ssanchezd@stanford.edu            DPRINTF(HWPrefetch, "%s:Found a pf canidate, inserting into prefetch queue\n", cache->name());
1986109Ssanchezd@stanford.edu            //temp calc this here...
1996109Ssanchezd@stanford.edu            pfIdentified++;
2006109Ssanchezd@stanford.edu            //create a prefetch memreq
201378SN/A            Request * prefetchReq = new Request(*addr, blkSize, 0);
2021706SN/A            PacketPtr prefetch;
2033114Sgblack@eecs.umich.edu            prefetch = new Packet(prefetchReq, MemCmd::HardPFReq, -1);
204378SN/A            prefetch->allocate();
2055748SSteve.Reinhardt@amd.com            prefetch->req->setThreadContext(pkt->req->getCpuNum(),
2065748SSteve.Reinhardt@amd.com                                            pkt->req->getThreadNum());
2075748SSteve.Reinhardt@amd.com
208378SN/A            prefetch->time = time + (*delay); //@todo ADD LATENCY HERE
209378SN/A            //... initialize
2101706SN/A
2113114Sgblack@eecs.umich.edu            //Check if it is already in the cache
212378SN/A            if (cacheCheckPush) {
213378SN/A                if (cache->inCache(prefetch->getAddr())) {
2141706SN/A                    addr++;
2153114Sgblack@eecs.umich.edu                    delay++;
216378SN/A                    continue;
217378SN/A                }
2181706SN/A            }
2193114Sgblack@eecs.umich.edu
220378SN/A            //Check if it is already in the miss_queue
221378SN/A            if (cache->inMissQueue(prefetch->getAddr())) {
2221706SN/A                addr++;
2233114Sgblack@eecs.umich.edu                delay++;
224378SN/A                continue;
2254118Sgblack@eecs.umich.edu            }
2264118Sgblack@eecs.umich.edu
2274118Sgblack@eecs.umich.edu            //Check if it is already in the pf buffer
2284118Sgblack@eecs.umich.edu            if (inPrefetch(prefetch->getAddr()) != pf.end()) {
229378SN/A                pfBufferHit++;
2301706SN/A                addr++;
2313114Sgblack@eecs.umich.edu                delay++;
232378SN/A                continue;
233378SN/A            }
2341706SN/A
2353114Sgblack@eecs.umich.edu            //We just remove the head if we are full
236360SN/A            if (pf.size() == size)
2375513SMichael.Adler@intel.com            {
2385513SMichael.Adler@intel.com                DPRINTF(HWPrefetch, "%s:Inserting into prefetch queue, it was full removing oldest\n", cache->name());
2395513SMichael.Adler@intel.com                pfRemovedFull++;
2405513SMichael.Adler@intel.com                pf.pop_front();
2415513SMichael.Adler@intel.com            }
2425513SMichael.Adler@intel.com
2435513SMichael.Adler@intel.com            pf.push_back(prefetch);
2445513SMichael.Adler@intel.com            prefetch->flags |= CACHE_LINE_FILL;
245511SN/A
2461706SN/A            //Make sure to request the bus, with proper delay
2473114Sgblack@eecs.umich.edu            cache->setMasterRequest(Request_PF, prefetch->time);
248511SN/A
2495513SMichael.Adler@intel.com            //Increment through the list
2505513SMichael.Adler@intel.com            addr++;
2515513SMichael.Adler@intel.com            delay++;
2525513SMichael.Adler@intel.com        }
253511SN/A    }
2541706SN/A}
2553114Sgblack@eecs.umich.edu
2561706SN/Astd::list<PacketPtr>::iterator
2571706SN/ABasePrefetcher::inPrefetch(Addr address)
2581706SN/A{
2591706SN/A    //Guaranteed to only be one match, we always check before inserting
2603114Sgblack@eecs.umich.edu    std::list<PacketPtr>::iterator iter;
2611706SN/A    for (iter=pf.begin(); iter != pf.end(); iter++) {
2621706SN/A        if (((*iter)->getAddr() & ~(Addr)(blkSize-1)) == address) {
2631706SN/A            return iter;
2641706SN/A        }
2653114Sgblack@eecs.umich.edu    }
2661706SN/A    return pf.end();
267511SN/A}
2686703Svince@csl.cornell.edu
2696703Svince@csl.cornell.edu
2706703Svince@csl.cornell.edu