Advertisement
ggn666

Stride Prefetcher

May 20th, 2025
204
0
10 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.23 KB | None | 0 0
  1. #include <list>
  2. #include <vector>
  3. #include <queue>
  4. #include <utility>
  5. #include <unordered_map>
  6. #include "base/types.hh"
  7.  
  8. // avoiding typedefs purposefully
  9.  
  10. class prefetchEntry
  11. {
  12. public:
  13.   //Addr pc;
  14.   //unsigned coreId;
  15.   std::pair<Addr, unsigned> pcAndCore;
  16.   std::queue<Addr> addrq;
  17.  
  18.   prefetchEntry(Addr _pc, unsigned _coreId, Addr _addr)
  19.   {
  20.     //pc = _pc;
  21.     //coreId = _coreId;
  22.     pcAndCore = std::make_pair((Addr)_pc, (unsigned)_coreId);
  23.     addrq.push(_addr);
  24.   }
  25.  
  26.   prefetchEntry(Addr _pc, unsigned _coreId)
  27.   {
  28.     //pc = _pc;
  29.     //coreId = _coreId;
  30.     pcAndCore = std::make_pair((Addr)_pc, (unsigned)_coreId);
  31.   }
  32.  
  33.  
  34.   bool operator==(const prefetchEntry& other) const
  35.   {
  36.     return (pcAndCore.first == other.pcAndCore.first && pcAndCore.second == other.pcAndCore.second);
  37.   }
  38.  
  39.   void print()
  40.   {
  41.     std::cout << "PC: " << std::hex << pcAndCore.first << std::dec << pcAndCore.second << std::hex << ", addrq: ";
  42.     if(addrq.size() == 1)
  43.       {
  44.     std::cout << addrq.front() << std::endl;
  45.       }
  46.     else if(addrq.size() == 2)
  47.       {
  48.     std::cout << addrq.front() << ", " << addrq.back() << std::endl;
  49.       }
  50.     else
  51.       {
  52.     std::cout << "NULL" << std::endl;
  53.       }
  54.  
  55.   }
  56. };
  57.  
  58. struct prefetchEntryHash
  59. {
  60.   template <class T1, class T2>
  61.   std::size_t operator() (const std::pair<T1, T2> &k) const
  62.   {
  63.     return std::hash<T1>()(k.first) ^ std::hash<T2>()(k.second);
  64.   }
  65. };
  66.  
  67. class prefetchTable
  68. {
  69. public:
  70.   // store block addresses, LRU kept at the end, MRU kept in  front
  71.   std::list<prefetchEntry> table;
  72.   std::unordered_map<std::pair<Addr, unsigned>, std::list<prefetchEntry>::iterator, prefetchEntryHash> ma;
  73.   unsigned degree;
  74.   unsigned size; //ways in a set
  75.  
  76.   void printInfo()
  77.   {
  78.     std::cout << "Size: " << size << " entries" << std::endl;
  79.     std::cout << "Degree: " << degree << std::endl;
  80.   }
  81.  
  82.   prefetchTable(unsigned _size, unsigned _degree)
  83.   {
  84.     size = _size;
  85.     degree = _degree;
  86.     //occupancy = 0;
  87.   }
  88.  
  89.   bool find(Addr _pc, unsigned _coreId)
  90.   {
  91.     //prefetchEntry entry(_pc, _coreId);
  92.     //auto it = std::find(table.begin(), table.end(), entry);
  93.     std::pair<Addr, unsigned> _pcAndCore = std::make_pair((Addr)_pc, (unsigned)_coreId);
  94.     if(ma.find(_pcAndCore) == ma.end())
  95.       {
  96.     //std::cout << "not found.\n";
  97.     return false;
  98.       }
  99.     else
  100.       {
  101.     //std::cout << "found.";
  102.     //(*it).print();
  103.     return true;
  104.       }
  105.  
  106.   }
  107.  
  108.   /*
  109.     std::vector<prefetchEntry>::iterator traverse(Addr _pc)
  110.     {
  111.     for(auto it = table.begin(); it != table.end(); ++it)
  112.     {
  113.     if(it->pc == _pc)
  114.     return it;
  115.     }
  116.     return table.end();
  117.     }
  118.   */
  119.  
  120.  
  121.  
  122.   // updates the set, returns whether it was a hit or miss
  123.   std::vector<Addr> access(Addr _pc, unsigned _coreId, Addr _addr)
  124.   {
  125.     std::vector<Addr> memoryBlocksToPrefetch;
  126.     // find
  127.     //prefetchEntry entry(_pc, _coreId);
  128.     //auto find_it = std::find(table.begin(), table.end(), entry);
  129.     std::pair<Addr, unsigned> _pcAndCore = std::make_pair((Addr)_pc, (unsigned)_coreId);
  130.     // not present in the table
  131.     if(ma.find(_pcAndCore) == ma.end())
  132.       {
  133.     //std::cout << "miss\n";
  134.     // table is full
  135.     if(table.size() == size)
  136.       {
  137.         // delete least recently used element
  138.         auto last = table.back();
  139.         table.pop_back();
  140.         ma.erase(last.pcAndCore);
  141.       }
  142.     table.push_front(prefetchEntry(_pc, _coreId, _addr));
  143.     ma[_pcAndCore] = table.begin();
  144.       }
  145.     else
  146.       {
  147.     //std::cout << "hit\n";
  148.     // get the iterator from the hashmap
  149.     auto find_it = ma[_pcAndCore];
  150.     size_t addrqsize = find_it->addrq.size();
  151.     assert(addrqsize >= 1 && addrqsize <= 2);
  152.     // can insert the addr
  153.     if(addrqsize < 2)
  154.       {
  155.         assert(addrqsize <= 1);
  156.         find_it->addrq.push(_addr);
  157.       }
  158.     else
  159.       {
  160.         assert(addrqsize == 2);
  161.         long old_stride = find_it->addrq.back() - find_it->addrq.front();
  162.         long new_stride = _addr - find_it->addrq.back();
  163.         //std::cout << "old stride = " << std::dec << stride << "\n";
  164.         //std::cout << "new stride = " << std::dec << new_stride << "\n";
  165.         if(old_stride == new_stride)
  166.           {
  167.  
  168.         /*
  169.         display();
  170.         std::cout << std::endl << std::endl;
  171.         std::cout << "Let's calculate stride: " << std::endl;
  172.         find_it->print();
  173.         std::cout << "access addr: " << _addr << std::endl;
  174.         //exit(0);
  175.         */
  176.         // TODO: compute memory blocks to prefetch
  177.         memoryBlocksToPrefetch = blocksToPrefetch(_addr, new_stride);
  178.           }
  179.         find_it->addrq.pop();
  180.         find_it->addrq.push(_addr);
  181.       }
  182.     auto moveToFront = *find_it;
  183.     //moveToFront.print();
  184.     table.erase(find_it);
  185.     //table.insert(table.begin(), moveToFront);
  186.     table.push_front(moveToFront);
  187.     ma[_pcAndCore] = table.begin();
  188.       }
  189.  
  190.     return memoryBlocksToPrefetch;
  191.   }
  192.  
  193.   std::vector<Addr> blocksToPrefetch(Addr lastAddress, long stride)
  194.   {
  195.     std::vector<Addr> returnVector;
  196.     for(int i = 0; i < degree; ++i)
  197.       {
  198.     lastAddress += stride;
  199.     returnVector.push_back(lastAddress);
  200.       }
  201.     return returnVector;
  202.   }
  203.  
  204.   // display contents of set
  205.   void display()
  206.   {
  207.     int idx = 0;
  208.     for (auto it = table.begin(); it != table.end(); it++)
  209.       {
  210.     std::cout << "<" << idx << ">" << "\t\t";
  211.     (*it).print();
  212.     ++idx;
  213.       }
  214.     std::cout << std::endl;
  215.   }
  216.  
  217. };
  218.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement