• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/genericProc/ssBackEnd/prefetch.h

00001 // Copyright 2010 Sandia Corporation. Under the terms
00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
00003 // Government retains certain rights in this software.
00004 // 
00005 // Copyright (c) 2007-2010, Sandia Corporation
00006 // All rights reserved.
00007 // 
00008 // This file is part of the SST software package. For license
00009 // information, see the LICENSE file in the top level directory of the
00010 // distribution.
00011 
00012 
00013 #ifndef _PREFETCH_H_
00014 #define _PREFETCH_H_
00015 
00016 #include "sst_config.h"
00017 #include <string>
00018 #include <queue>
00019 #include <set>
00020 #include <map>
00021 #ifdef HAVE_UNORDERED_SET
00022 # include <unordered_set>
00023 #elif defined(HAVE_TR1_UNORDERED_SET)
00024 # include <tr1/unordered_set>
00025 #else /* unordered_set */
00026 # ifdef __GNUC__
00027 #  if __GNUC__ < 3
00028 #   include <hash_set.h>
00029 namespace extension { using ::hash_set; }; // inherit globals
00030 #  else
00031 #   include <ext/hash_set>
00032 //#   include <backward/hash_set>
00033 #   if __GNUC__ == 3 && __GNUC_MINOR__ == 0
00034 namespace extension = std; // GCC 3.0
00035 #   else
00036 namespace extension = ::__gnu_cxx; // GCC 3.1 and later
00037 #   endif
00038 #  endif
00039 # else
00040 #  include <hash_set>
00041 # endif
00042 #endif /* unordered_set */
00043 #include <list>
00044 #include "FE/pool.h"
00045 #include "ssb_DMA_fakeInst.h"
00046 #include "instruction.h"
00047 
00048 using namespace std;
00049 
00050 //: Interface for a prefetch-aware memory controller
00051 class prefetchMC {
00052 public:
00053   virtual ~prefetchMC() {;}
00054   //: Returns bandwidth load
00055   //
00056   // a positive number means low load, a negative means a backup.
00057   virtual int load()=0;
00058 };
00059 
00060 //: Interface for a prefetching processor
00061 //
00062 // This is what a prefetcher expects of its processor. 
00063 class prefetchProc {  
00064 public:
00065   virtual ~prefetchProc() {;}
00066   //: Check if a given address is in cache
00067   virtual bool checkCache(const simAddress)=0;
00068   //: insert a value to the cache
00069   virtual void insertCache(const simAddress)=0;
00070   //: Tell processor to send a memory request
00071   virtual void sendToMem(instruction *p)=0;
00072   //: Tell processor to 'wake up' an instruction 
00073   virtual void wakeUpPrefetched(instruction*)=0;
00074   //: current cycle count
00075   virtual uint64_t getCurrentCycle()=0;
00076 };
00077 
00078 //: Prefetcher
00079 //
00080 // A semi-generic prefetcher. Currently only implements OBL prefetch. 
00081 class prefetcher {
00082   typedef map<string,string> paramMap_t;
00083   //: config parameters
00084   paramMap_t params;
00085   int getValue(string s) {
00086     paramMap_t::iterator i = params.find(s);
00087     if (i != params.end()) {
00088       printf("getValue %s: %s (%d)\n", s.c_str(), i->second.c_str(), atoi(i->second.c_str()));
00089       return atoi(i->second.c_str());
00090     } else {
00091       return -1;
00092     }
00093   }
00094   string getStrValue(string s) {
00095     paramMap_t::iterator i = params.find(s);
00096     if (i != params.end()) {
00097       printf("getStrValue %s: %s\n", s.c_str(), i->second.c_str());
00098       return i->second;
00099     } else {
00100       return "";
00101     }
00102   }
00103 
00104   int cacheShift;
00105 
00106   //: pointer to "parent" processor
00107   prefetchProc *proc;
00108   //: Use Tagged OBL?
00109   int tagged;
00110   //: Degree of prefetch
00111   //
00112   // i.e. number of lines ahead to prefetch
00113   int degree;
00114   //: Use Adaptive prefetch?
00115   int adaptive;
00116   //: Mask to determine when to adapt
00117   unsigned long long adaptQuantaMask;
00118   //: Maximum prefetch degree 
00119   //
00120   // for adaptive prefetching
00121   int adaptMax;
00122   //: Degree decrement threshold
00123   //
00124   // for adaptive prefetching
00125   int decDeg;
00126   //: Degree increment threshold
00127   //
00128   // for adaptive prefetching
00129   int incDeg;
00130   //: page shift for prefetcher
00131   // a prefetcher will not fetch over a page boundary
00132   int pageShift;
00133   //: Set of outstanding "fake" instructions
00134   //
00135   // Used to detect if a given parcel was sent on our behest.
00136   set<fakeDMAInstruction*> fakes;
00137   //: Set of requested addresses
00138   set<simAddress> addrs;
00139 
00140 #ifdef HAVE_UNORDERED_SET
00141   typedef std::unordered_set<simAddress> inCacheSet;
00142 #elif defined(HAVE_TR1_UNORDERED_SET)
00143   typedef std::tr1::unordered_set<simAddress> inCacheSet;
00144 #else /* unordered_set */
00145 # ifdef __GNUC__
00146 #  if __GNUC__ < 3
00147   typedef hash_set<simAddress> inCacheSet;
00148 #  elif __GNUC__ == 3 && __GNUC_MINOR__ == 0
00149   typedef std::hash_set<simAddress> inCacheSet; // GCC 3.0
00150 #  else
00151   typedef __gnu_cxx::hash_set<simAddress> inCacheSet; // GCC 3.1 and later
00152 #  endif /* __GNUC__ versions */
00153 # else /* __GNUC__ */
00154   typedef std::hash_set<simAddress> inCacheSet; // non-GCC
00155 # endif
00156 #endif
00157 
00158   //: Set of addresses we placed in the cache
00159   //
00160   // used to determine prefetch hit rate
00161   inCacheSet reqInCache;
00162   //: Pool of fake instructions
00163   static pool<fakeDMAInstruction> fakeInst;
00164   //: Number of requests issued
00165   unsigned long long requestsIssued;
00166   //: Number of "hits" on requests
00167   unsigned long long requestsHit;
00168   //: Total memory requests
00169   unsigned long long totalReq;
00170   //: Page limited request cancels
00171   //
00172   // Number of requests we didn't issue because they crossed a page
00173   // boundary.
00174   unsigned long long overPage;
00175   unsigned long long tooLate;
00176   //: Number of times we adaptivly changed the degree
00177   int adaptions;
00178   //: Requests in current quanta
00179   //
00180   // Used to calculate adaptive hit rate
00181   int subTotalReq;
00182   //: Request 'hits' in current quanta
00183   //
00184   // Used to calculate adaptive hit rate
00185   int subRequestsHit;
00186 
00187   //: number of stream requests
00188   unsigned long long streamReq;
00189 
00190   unsigned long long streamsDetected;
00191 
00192   //: should the prefetcher take load into account
00193   int loadAware;
00194 
00195   typedef list<instruction *> wakeUpList_t;
00196   typedef map<simAddress, wakeUpList_t > wakeUpMap_t;
00197   //: Map of instructions which will be woken
00198   //
00199   // Map key is the address which was being prefetched, map data is a
00200   // list of instruction to be woken.
00201   wakeUpMap_t wakeUpMap;
00202   //: a prefetch aware MC, capable of giving load information
00203   prefetchMC *mc;
00204 
00205   /* Streaming prefetcher stuff */
00206 
00207   //: set of cache lines the stream prefetcher has issued
00208   set<simAddress> streamIssued;
00209   //: Set of cachelines placed in the cache by the streaming prefetcher
00210   inCacheSet reqInSCache;
00211   //: Number of times data which was streamed in was touched
00212   unsigned long long streamRequestsHit;
00213 
00214   //: number of prefetch streams
00215   int streams;
00216   //: stream detection window
00217   int windowL;
00218   //: Necessary stream length before detection
00219   int detLeng;
00220   //: Stream round robin counter
00221   int rr;
00222   //: Current streams
00223   //
00224   // each element is the last address fetched, shifted by the cacheShift
00225   set<simAddress> streamSet;
00226   //: Count of items in window
00227   int inWin;
00228   //: temporal record of when blocks were seen
00229   std::queue<simAddress> window;
00230   //: list of pages which have beens streamed recently
00231   deque<simAddress> recentStreams;
00232   //: window of recently seen blocks
00233   //
00234   // used to detect streams
00235   inCacheSet contigCount;
00236   //: last block seen
00237   //
00238   // for a simple optimization
00239   simAddress lastBlock;
00240   void detectStream(const simAddress);
00241 
00242   //: collect prefetch performance stats or not
00243   //
00244   // not collecting stats improves performance by a small percentage
00245   int stats;
00246 
00247   bool memReq(const simAddress, bool &);
00248 public:
00249   prefetcher(paramMap_t, prefetchProc *, prefetchMC *);
00250   typedef enum {INST, DATA} memAccType;
00251   typedef enum {READ,WRITE} memAccDir;
00252   void memRef(const simAddress, const memAccType, const memAccDir, bool hit);
00253   void reportCacheEject(const simAddress);
00254   bool handleParcel(instruction *p);
00255   bool isPreFetching(const simAddress);
00256   void setWakeUp(instruction *, simAddress);
00257   void finish();
00258   void preTic();
00259 };
00260 
00261 #endif
00262 
00263 

Generated on Fri Oct 22 2010 11:02:24 for SST by  doxygen 1.7.1