Skip to content

Commit

Permalink
Made stride tracking a struct, tweaked LRU tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
ngober committed Jan 27, 2022
1 parent 4a24af8 commit e527398
Showing 1 changed file with 26 additions and 21 deletions.
47 changes: 26 additions & 21 deletions prefetcher/ip_stride/ip_stride.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,48 @@ constexpr int PREFETCH_DEGREE = 3;

struct tracker_entry
{
uint64_t ip = 0; // the IP we're tracking
uint64_t last_cl_addr = 0; // the last address accessed by this IP
int64_t last_stride = 0; // the stride between the last two addresses accessed by this IP
uint64_t lru = 0; // use LRU to evict old IP trackers
uint64_t ip = 0; // the IP we're tracking
uint64_t last_cl_addr = 0; // the last address accessed by this IP
int64_t last_stride = 0; // the stride between the last two addresses accessed by this IP
uint64_t last_used_cycle = 0; // use LRU to evict old IP trackers
};

struct lookahead_entry
{
uint64_t address = 0;
int64_t stride = 0;
int degree = 0;
};

constexpr std::size_t TRACKER_SETS = 256;
constexpr std::size_t TRACKER_WAYS = 4;
std::map<CACHE*, std::tuple<uint64_t, int64_t, int>> lookahead; // pf_address, stride, degree
std::map<CACHE*, lookahead_entry> lookahead;
std::map<CACHE*, std::array<tracker_entry, TRACKER_SETS*TRACKER_WAYS>> trackers;

void CACHE::l2c_prefetcher_initialize()
void CACHE::prefetcher_initialize()
{
std::cout << this->NAME << " IP-based stride prefetcher" << std::endl;
std::cout << NAME << " IP-based stride prefetcher" << std::endl;
}

void CACHE::prefetcher_cycle_operate()
{
// If a lookahead is active
if (auto [pf_address, stride, degree] = lookahead[this]; pf_address != 0)
if (auto [old_pf_address, stride, degree] = lookahead[this]; old_pf_address != 0)
{
auto pf_address = old_pf_address + (stride << LOG2_BLOCK_SIZE);

// If the next step would exceed the degree or run off the page, stop
if (degree < PREFETCH_DEGREE && (virtual_prefetch || ((pf_address + (stride << LOG2_BLOCK_SIZE)) >> LOG2_PAGE_SIZE) == (pf_address >> LOG2_PAGE_SIZE)))
if (degree < PREFETCH_DEGREE && (virtual_prefetch || (pf_address >> LOG2_PAGE_SIZE) == (old_pf_address >> LOG2_PAGE_SIZE)))
{
// calculate prefetch address
pf_address += stride << LOG2_BLOCK_SIZE;

// check the MSHR occupancy to decide if we're going to prefetch to the L2 or LLC
prefetch_line(0, 0, pf_address, (get_occupancy(0,pf_address) < get_size(0,pf_address)/2) ? FILL_L2 : FILL_LLC, 0);
// check the MSHR occupancy to decide if we're going to prefetch to this level or not
bool success = prefetch_line(0, 0, pf_address, (get_occupancy(0,pf_address) < get_size(0,pf_address)/2), 0);
if (success)
lookahead[this] = {pf_address, stride, degree+1};
}
else
{
pf_address = 0;
lookahead[this] = {};
}

lookahead[this] = {pf_address, stride, degree+1};
}
}

Expand All @@ -69,17 +75,16 @@ uint32_t CACHE::prefetcher_cache_operate(uint64_t addr, uint64_t ip, uint8_t cac
// Initialize prefetch state unless we somehow saw the same address twice in a row
// or if this is the first time we've seen this stride
if (stride != 0 && stride == found->last_stride)
lookahead[this] = {cl_addr << LOG2_BLOCK_SIZE, stride, 0};
lookahead[this] = {cl_addr, stride, 0};
}
else
{
// replace by LRU
found = std::max_element(set_begin, set_end, [](tracker_entry x, tracker_entry y){ return x.lru < y.lru; });
found = std::min_element(set_begin, set_end, [](tracker_entry x, tracker_entry y){ return x.last_used_cycle < y.last_used_cycle; });
}

// update tracking set
std::for_each(set_begin, set_end, [](tracker_entry &x){ x.lru++; });
*found = {ip, cl_addr, stride, 0};
*found = {ip, cl_addr, stride, current_cycle};

return metadata_in;
}
Expand Down

0 comments on commit e527398

Please sign in to comment.