Skip to content

Commit

Permalink
Add an implementation of a true LRU cache replacement policy
Browse files Browse the repository at this point in the history
  • Loading branch information
bdutro authored and klingaard committed Apr 16, 2024
1 parent ee08219 commit 3a668fe
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 2 deletions.
83 changes: 83 additions & 0 deletions sparta/cache/LRUReplacement.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// <LRUReplacement.hpp> -*- C++ -*-

//!
//! \file LRUReplacement.hpp
//! \brief Provides a simple true LRU implementation
//!

#pragma once

#include <vector>
#include <list>

#include "ReplacementIF.hpp"

namespace sparta::cache
{
// This class models true LRU with an std::list of way indices. The head of the list is LRU, and
// the tail is MRU. An std::vector of iterators to the list is used to provide constant-time
// index -> iterator lookup. A way is placed at LRU or MRU by moving its respective iterator to
// the beginning or end of the list.
class LRUReplacement : public ReplacementIF
{
public:
explicit LRUReplacement(const uint32_t num_ways) : ReplacementIF(num_ways)
{
for (uint32_t i = 0; i < num_ways; ++i)
{
way_map_.emplace_back(lru_stack_.emplace(lru_stack_.end(), i));
}
}

ReplacementIF* clone() const override
{
return new LRUReplacement(num_ways_);
}

void touchLRU(uint32_t way) override
{
auto lru_it = way_map_[way];
lru_stack_.splice(lru_stack_.begin(), lru_stack_, lru_it);
}

void touchLRU(uint32_t way, const std::vector<uint32_t> & way_order) override
{
sparta_assert(false, "Not implemented");
}

void touchMRU(uint32_t way) override
{
auto lru_it = way_map_[way];
lru_stack_.splice(lru_stack_.end(), lru_stack_, lru_it);
}

void touchMRU(uint32_t way, const std::vector<uint32_t> & way_order) override
{
sparta_assert(false, "Not implemented");
}

uint32_t getLRUWay() const override { return lru_stack_.front(); }

uint32_t getLRUWay(const std::vector<uint32_t> & way_order) override
{
sparta_assert(false, "Not implemented");
}

uint32_t getMRUWay() const override { return lru_stack_.back(); }

uint32_t getMRUWay(const std::vector<uint32_t> & way_order) override
{
sparta_assert(false, "Not implemented");
}

void lockWay(uint32_t way) override
{
sparta_assert(way < num_ways_);
sparta_assert(false, "Not implemented");
}

private:
std::list<uint32_t> lru_stack_;
std::vector<std::list<uint32_t>::const_iterator> way_map_;
};
} // namespace shinro
1 change: 1 addition & 0 deletions sparta/test/cache/simple_cache/DL1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "cache/SimpleCache.hpp"
#include "cache/TreePLRUReplacement.hpp"
#include "cache/LRUReplacement.hpp"
#include "cache/LineData.hpp"
#include "cache/BlockingMemoryIF.hpp"

Expand Down
4 changes: 2 additions & 2 deletions sparta/test/cache/simple_cache/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dl1_(32, // 32KB in size
LINE_SIZE, // line size
LINE_SIZE, // stride
sparta::cache::LineData(LINE_SIZE), // line_size
sparta::cache::TreePLRUReplacement(8) ); // num_ways
sparta::cache::LRUReplacement(8) ); // num_ways

sparta::cache::SimpleCache<sparta::cache::LineData>
l2_(512, // 512KB
Expand All @@ -31,7 +31,7 @@ btb_a_(4, // 4kb
LINE_SIZE, // line size
LINE_SIZE, // stride
sparta::cache::LineData(LINE_SIZE), // default line copied for initialization
sparta::cache::TreePLRUReplacement(4) ); // num_ways
sparta::cache::LRUReplacement(4) ); // num_ways

sparta::cache::SimpleCache2<sparta::cache::LineData>
btb_b_(4096, // 4kb
Expand Down

0 comments on commit 3a668fe

Please sign in to comment.