stride.hh revision 2810
11689SN/A/*
29444SAndreas.Sandberg@ARM.com * Copyright (c) 2005 The Regents of The University of Michigan
39913Ssteve.reinhardt@amd.com * All rights reserved.
47854SAli.Saidi@ARM.com *
57854SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
67854SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
77854SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
87854SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
97854SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
107854SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
117854SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
127854SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
137854SAli.Saidi@ARM.com * contributors may be used to endorse or promote products derived from
147854SAli.Saidi@ARM.com * this software without specific prior written permission.
152329SN/A *
161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271689SN/A *
281689SN/A * Authors: Ron Dreslinski
291689SN/A */
301689SN/A
311689SN/A/**
321689SN/A * @file
331689SN/A * Describes a strided prefetcher based on template policies.
341689SN/A */
351689SN/A
361689SN/A#ifndef __MEM_CACHE_PREFETCH_STRIDE_PREFETCHER_HH__
371689SN/A#define __MEM_CACHE_PREFETCH_STRIDE_PREFETCHER_HH__
381689SN/A
391689SN/A#include "base/misc.hh" // fatal, panic, and warn
402665Ssaidi@eecs.umich.edu
412665Ssaidi@eecs.umich.edu#include "mem/cache/prefetch/prefetcher.hh"
422935Sksewell@umich.edu
431689SN/A/**
441689SN/A * A template-policy based cache. The behavior of the cache can be altered by
451060SN/A * supplying different template policies. TagStore handles all tag and data
461060SN/A * storage @sa TagStore. Buffering handles all misses and writes/writebacks
473773Sgblack@eecs.umich.edu * @sa MissQueue. Coherence handles all coherence policy details @sa
486329Sgblack@eecs.umich.edu * UniCoherence, SimpleMultiCoherence.
496658Snate@binkert.org */
501717SN/Atemplate <class TagStore, class Buffering>
519913Ssteve.reinhardt@amd.comclass StridePrefetcher : public Prefetcher<TagStore, Buffering>
528232Snate@binkert.org{
538232Snate@binkert.org  protected:
549527SMatt.Horsnell@arm.com
555529Snate@binkert.org    Buffering* mq;
561060SN/A    TagStore* tags;
576221Snate@binkert.org
586221Snate@binkert.org    class strideEntry
591061SN/A    {
605529Snate@binkert.org      public:
614329Sktlim@umich.edu        Addr IAddr;
624329Sktlim@umich.edu        Addr MAddr;
632292SN/A        int stride;
642292SN/A        int64_t confidence;
652292SN/A
662292SN/A/*	bool operator < (strideEntry a,strideEntry b)
675529Snate@binkert.org        {
689920Syasuko.eckert@amd.com            if (a.confidence == b.confidence) {
699920Syasuko.eckert@amd.com                return true; //??????
701060SN/A            }
712292SN/A            else return a.confidence < b.confidence;
728907Slukefahr@umich.edu            }*/
732292SN/A    };
742292SN/A    Addr* lastMissAddr[64/*MAX_CPUS*/];
752292SN/A
762292SN/A    std::list<strideEntry*> table[64/*MAX_CPUS*/];
772292SN/A    Tick latency;
782292SN/A    int degree;
792292SN/A    bool useCPUId;
801060SN/A
811060SN/A
821061SN/A  public:
831060SN/A
842292SN/A    StridePrefetcher(int size, bool pageStop, bool serialSquash,
851062SN/A                     bool cacheCheckPush, bool onlyData,
861062SN/A                     Tick latency, int degree, bool useCPUId)
878240Snate@binkert.org        :Prefetcher<TagStore, Buffering>(size, pageStop, serialSquash,
881062SN/A                                         cacheCheckPush, onlyData),
891062SN/A         latency(latency), degree(degree), useCPUId(useCPUId)
901062SN/A    {
918240Snate@binkert.org    }
921062SN/A
931062SN/A    ~StridePrefetcher() {}
941062SN/A
958240Snate@binkert.org    void calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses,
961062SN/A                           std::list<Tick> &delays)
971062SN/A    {
982301SN/A//	Addr blkAddr = pkt->paddr & ~(Addr)(this->blkSize-1);
998240Snate@binkert.org        int cpuID = pkt->cpu_num;
1002301SN/A        if (!useCPUId) cpuID = 0;
1012301SN/A
1022292SN/A        /* Scan Table for IAddr Match */
1038240Snate@binkert.org/*	std::list<strideEntry*>::iterator iter;
1042292SN/A        for (iter=table[cpuID].begin();
1052292SN/A             iter !=table[cpuID].end();
1061062SN/A             iter++) {
1078240Snate@binkert.org            if ((*iter)->IAddr == pkt->pc) break;
1081062SN/A        }
1091062SN/A
1101062SN/A        if (iter != table[cpuID].end()) {
1118240Snate@binkert.org            //Hit in table
1121062SN/A
1131062SN/A            int newStride = blkAddr - (*iter)->MAddr;
1141062SN/A            if (newStride == (*iter)->stride) {
1158240Snate@binkert.org                (*iter)->confidence++;
1161062SN/A            }
1171062SN/A            else {
1181062SN/A                (*iter)->stride = newStride;
1198240Snate@binkert.org                (*iter)->confidence--;
1202292SN/A            }
1211062SN/A
1221062SN/A            (*iter)->MAddr = blkAddr;
1238240Snate@binkert.org
1242292SN/A            for (int d=1; d <= degree; d++) {
1251062SN/A                Addr newAddr = blkAddr + d * newStride;
1262292SN/A                if (this->pageStop &&
1278240Snate@binkert.org                    (blkAddr & ~(TheISA::VMPageSize - 1)) !=
1282292SN/A                    (newAddr & ~(TheISA::VMPageSize - 1)))
1292292SN/A                {
1301062SN/A                    //Spanned the page, so now stop
1318240Snate@binkert.org                    this->pfSpanPage += degree - d + 1;
1321062SN/A                    return;
1331062SN/A                }
1341062SN/A                else
1358240Snate@binkert.org                {
1361062SN/A                    addresses.push_back(newAddr);
1371062SN/A                    delays.push_back(latency);
1381062SN/A                }
1398240Snate@binkert.org            }
1401062SN/A        }
1411062SN/A        else {
1421062SN/A            //Miss in table
1438240Snate@binkert.org            //Find lowest confidence and replace
1441062SN/A
1451062SN/A        }
1461062SN/A*/    }
1478240Snate@binkert.org};
1481062SN/A
1491062SN/A#endif // __MEM_CACHE_PREFETCH_STRIDE_PREFETCHER_HH__
1502301SN/A