Skip to content

Commit bdff774

Browse files
govardhnnorion160kathlenemagnusjeffnye-ghjeff
authored
Adding Support: Configurable Cache Replacement Policies (#230)
Building on [Issue#61](#61), this merge request proposes to add configurable cache-replacement policies to Olympia. --------- Signed-off-by: Isaac David <61389980+orion160@users.noreply.github.com> Signed-off-by: Govardhan <saigov14@gmail.com> Co-authored-by: Isaac David <61389980+orion160@users.noreply.github.com> Co-authored-by: Kathlene Magnus <kathlene.hurt@gmail.com> Co-authored-by: jeffnye-gh <112903691+jeffnye-gh@users.noreply.github.com> Co-authored-by: jeff <jeffnye-gh@github.com>
1 parent f03f0c3 commit bdff774

File tree

12 files changed

+87
-30
lines changed

12 files changed

+87
-30
lines changed

.github/actions/build/entrypoint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ if [ $? -ne 0 ]; then
4848
echo "ERROR: Cmake for olympia failed"
4949
exit 1
5050
fi
51-
make -j$NUM_CORES regress
51+
make -j$NUM_CORES VERBOSE=1 regress
5252
BUILD_OLYMPIA=$?
5353
if [ ${BUILD_OLYMPIA} -ne 0 ]; then
5454
echo "ERROR: build/regress of olympia FAILED!!!"

.github/workflows/macos-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
with:
3939
repository: sparcians/map
4040
path: map
41-
ref: map_v2.0.13
41+
ref: map_v2.0.21
4242

4343
# Setup Conda and build environment
4444
- name: Grab Python v3.8

.github/workflows/ubuntu-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
with:
3939
repository: sparcians/map
4040
path: map
41-
ref: map_v2.0.13
41+
ref: map_v2.0.21
4242

4343
# Setup Conda and build environment
4444
- name: Grab Python v3.8

CONTRIBUTORS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ The following people from multiple organizations have contributed to this projec
1212
* (Condor Computing)[https://condorcomputing.com]
1313
* (Jeff Nye)[https://github.com/jeffnye-gh]
1414

15+
* (InCore Semiconductors)[https://incoresemi.com/]
16+
* (Sai Govardhan)[https://github.com/govardhnn]
17+
1518
List is incomplete and more contributor names/organizations to be added.

core/CacheFuncModel.hpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#pragma once
32

43
#include "sparta/utils/SpartaAssert.hpp"
@@ -8,6 +7,7 @@
87
#include "cache/ReplacementIF.hpp"
98
#include "cache/preload/PreloadableIF.hpp"
109
#include "cache/preload/PreloadableNode.hpp"
10+
#include "ReplacementFactory.hpp"
1111

1212
using namespace std::placeholders;
1313
namespace olympia
@@ -39,7 +39,6 @@ namespace olympia
3939
BasicCacheItem::operator=(rhs);
4040
line_size_ = rhs.line_size_;
4141
valid_ = rhs.valid_;
42-
4342
return *this;
4443
}
4544

@@ -91,28 +90,37 @@ namespace olympia
9190
}; // class SimpleCacheLine
9291

9392
class CacheFuncModel : public sparta::cache::SimpleCache2<SimpleCacheLine>,
94-
public sparta::TreeNode,
95-
public sparta::cache::PreloadableIF,
96-
public sparta::cache::PreloadDumpableIF
97-
93+
public sparta::TreeNode,
94+
public sparta::cache::PreloadableIF,
95+
public sparta::cache::PreloadDumpableIF
9896
{
9997
public:
10098
using Handle = std::shared_ptr<CacheFuncModel>;
99+
100+
// Constructor for the cache functional model
101+
// @param parent The parent tree node
102+
// @param cache_size_kb Size of the cache in KB
103+
// @param line_size Cache line size in bytes
104+
// @param replacement_policy Name of the replacement policy to use
105+
// @param associativity Number of ways in the cache
101106
CacheFuncModel(sparta::TreeNode* parent,
102-
uint64_t cache_size_kb,
103-
uint64_t line_size,
104-
const sparta::cache::ReplacementIF& rep) :
105-
sparta::cache::SimpleCache2<SimpleCacheLine> (cache_size_kb,
106-
line_size,
107-
line_size,
108-
SimpleCacheLine(line_size),
109-
rep),
107+
uint64_t cache_size_kb,
108+
uint64_t line_size,
109+
const std::string& replacement_policy,
110+
uint32_t associativity) :
111+
sparta::cache::SimpleCache2<SimpleCacheLine>(
112+
cache_size_kb,
113+
line_size,
114+
line_size,
115+
SimpleCacheLine(line_size),
116+
*ReplacementFactory::selectReplacementPolicy(replacement_policy, associativity)),
110117
sparta::TreeNode(parent, "l1cache", "Simple L1 DCache"),
111118
sparta::cache::PreloadableIF(),
112119
sparta::cache::PreloadDumpableIF(),
113120
preloadable_(this, std::bind(&CacheFuncModel::preloadPkt_, this, _1),
114-
std::bind(&CacheFuncModel::preloadDump_, this, _1))
121+
std::bind(&CacheFuncModel::preloadDump_, this, _1))
115122
{}
123+
116124
private:
117125
/**
118126
* Implement a preload by just doing a fill to the va in the packet.
@@ -132,7 +140,6 @@ namespace olympia
132140
sparta_assert(getLine(va) != nullptr);
133141
}
134142
return true;
135-
136143
}
137144

138145
void preloadDump_(sparta::cache::PreloadEmitter& emitter) const override
@@ -160,6 +167,7 @@ namespace olympia
160167
emitter << sparta::cache::PreloadEmitter::EndSeq;
161168
emitter << sparta::cache::PreloadEmitter::EndMap;
162169
}
170+
163171
//! Provide a preloadable node that hangs off and just returns
164172
//! the preloadPkt call to us.
165173
sparta::cache::PreloadableNode preloadable_;

core/ReplacementFactory.hpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#include "cache/ReplacementIF.hpp"
4+
#include "cache/TreePLRUReplacement.hpp"
5+
#include "cache/LRUReplacement.hpp"
6+
#include <memory>
7+
#include <string>
8+
#include <stdexcept>
9+
10+
namespace olympia
11+
{
12+
/**
13+
* @brief Factory class for creating cache replacement policies
14+
*
15+
* Creates and returns Sparta replacement policies based on the policy name.
16+
* Currently supports:
17+
* - "TreePLRU" (Tree-based Pseudo-LRU)
18+
* - "LRU" (Least Recently Used)
19+
* - "MRU" (Most Recently Used - implemented using LRU's infrastructure)
20+
*/
21+
class ReplacementFactory {
22+
public:
23+
/**
24+
* @brief Create a replacement policy instance
25+
* @param policy_name Name of the policy to create ("TreePLRU", "LRU", or "MRU")
26+
* @param num_ways Number of ways in the cache set
27+
* @return Unique pointer to the created replacement policy
28+
* @throws std::invalid_argument if policy name is not recognized
29+
*/
30+
static std::unique_ptr<sparta::cache::ReplacementIF> selectReplacementPolicy(
31+
const std::string& policy_name,
32+
uint32_t num_ways)
33+
{
34+
if (policy_name == "TreePLRU") {
35+
return std::unique_ptr<sparta::cache::ReplacementIF>(
36+
new sparta::cache::TreePLRUReplacement(num_ways));
37+
}
38+
else if (policy_name == "LRU" || policy_name == "MRU") {
39+
// Both LRU and MRU use the same LRUReplacement class
40+
// The difference is in how the cache controller uses touchLRU/touchMRU
41+
return std::unique_ptr<sparta::cache::ReplacementIF>(
42+
new sparta::cache::LRUReplacement(num_ways));
43+
}
44+
45+
throw std::invalid_argument("Unknown replacement policy: " + policy_name +
46+
". Supported policies are: TreePLRU, LRU, MRU");
47+
}
48+
};
49+
} // namespace olympia

core/fetch/ICache.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,9 @@ namespace olympia {
3737
const uint32_t l1_line_size = p->l1_line_size;
3838
const uint32_t l1_size_kb = p->l1_size_kb;
3939
const uint32_t l1_associativity = p->l1_associativity;
40-
std::unique_ptr<sparta::cache::ReplacementIF> repl(new sparta::cache::TreePLRUReplacement
41-
(l1_associativity));
42-
l1_cache_.reset(new CacheFuncModel(getContainer(), l1_size_kb, l1_line_size, *repl));
40+
const std::string& replacement_policy = p->replacement_policy;
41+
l1_cache_.reset(new CacheFuncModel(getContainer(), l1_size_kb, l1_line_size, replacement_policy, l1_associativity));
4342
sparta::StartupEvent(node, CREATE_SPARTA_HANDLER(ICache, sendInitialCredits_));
44-
45-
4643
}
4744

4845
void ICache::sendInitialCredits_()

core/fetch/ICache.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ namespace olympia
4444
PARAMETER(uint32_t, l1_line_size, 64, "IL1 line size (power of 2)")
4545
PARAMETER(uint32_t, l1_size_kb, 32, "Size of IL1 in KB (power of 2)")
4646
PARAMETER(uint32_t, l1_associativity, 8, "IL1 associativity (power of 2)")
47+
PARAMETER(std::string, replacement_policy, "TreePLRU", "IL1 cache replacement policy")
4748
PARAMETER(uint32_t, cache_latency, 1, "Assumed latency of the memory system")
4849
PARAMETER(bool, l1_always_hit, false, "IL1 will always hit")
4950
};

core/lsu/DCache.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ namespace olympia
5252
const uint32_t l1_line_size = p->l1_line_size;
5353
const uint32_t l1_size_kb = p->l1_size_kb;
5454
const uint32_t l1_associativity = p->l1_associativity;
55-
std::unique_ptr<sparta::cache::ReplacementIF> repl(
56-
new sparta::cache::TreePLRUReplacement(l1_associativity));
57-
l1_cache_.reset(new CacheFuncModel(getContainer(), l1_size_kb, l1_line_size, *repl));
55+
l1_cache_.reset(new CacheFuncModel(getContainer(), l1_size_kb, l1_line_size, p->replacement_policy, l1_associativity));
5856
addr_decoder_ = l1_cache_->getAddrDecoder();
5957
}
6058

core/lsu/DCache.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ namespace olympia
2929
PARAMETER(uint32_t, l1_associativity, 8, "DL1 associativity (power of 2)")
3030
PARAMETER(bool, l1_always_hit, false, "DL1 will always hit")
3131
PARAMETER(uint32_t, mshr_entries, 8, "Number of MSHR Entries")
32+
PARAMETER(std::string, replacement_policy, "TreePLRU", "Cache Replacement Policy")
3233
};
3334

3435
static const char name[];

0 commit comments

Comments
 (0)