Skip to content

Commit

Permalink
i#5995: Add exclusive mode to drcachesim. (#6454)
Browse files Browse the repository at this point in the history
Allow caches to be configured with an exclusive policy to function as
victim caches. Caches with this policy are only populated by lines
evicted from their children.

Also added accessors for snoop filter stats to cache_simulator_t.

Fixes #5995
  • Loading branch information
brettcoon authored Nov 17, 2023
1 parent 10ea92a commit 365b1a1
Show file tree
Hide file tree
Showing 17 changed files with 467 additions and 89 deletions.
4 changes: 3 additions & 1 deletion clients/drcachesim/docs/drcachesim.dox.in
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,7 @@ sets the corresponding option with the same name described in \ref sec_drcachesi
- cpu_scheduling \<bool\>
- verbose \<unsigned int\>
- coherence \<bool\>
- coherent \<bool\> - (alias for coherence)
- use_physical \<bool\>

Supported cache parameters and their value types:
Expand All @@ -1018,6 +1019,7 @@ Supported cache parameters and their value types:
- size \<unsigned int, power of 2\>
- assoc \<unsigned int, power of 2\>
- inclusive \<bool\>
- exclusive \<bool\>
- parent \<string\>
- replace_policy \<string, one of "LRU", "LFU", or "FIFO"\>
- prefetcher \<string, one of "nextline" or "none"\>
Expand Down Expand Up @@ -1061,7 +1063,7 @@ P0L2 { // P0 L2 unified cache
LLC { // LLC
size 1M
assoc 16
inclusive true
exclusive true
parent memory
replace_policy LRU
miss_file misses.txt
Expand Down
27 changes: 24 additions & 3 deletions clients/drcachesim/reader/config_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ config_reader_t::configure(std::istream *config_file, cache_simulator_knobs_t &k
ERRMSG("Error reading verbose from the configuration file\n");
return false;
}
} else if (param == "coherence") {
} else if (param == "coherence" || param == "coherent") {
// Whether to simulate coherence
std::string bool_val;
if (!(*fin_ >> bool_val)) {
Expand Down Expand Up @@ -203,7 +203,7 @@ config_reader_t::configure_cache(cache_params_t &cache)
return false;
}
if (c != '{') {
ERRMSG("Expected '{' before cache params\n");
ERRMSG("Expected '{' between '%s' and cache params\n", cache.name.c_str());
return false;
}

Expand Down Expand Up @@ -273,15 +273,36 @@ config_reader_t::configure_cache(cache_params_t &cache)
// Is the cache inclusive of its children.
std::string bool_val;
if (!(*fin_ >> bool_val)) {
ERRMSG("Error reading cache inclusivity from "
ERRMSG("Error reading inclusive cache policy from "
"the configuration file\n");
return false;
}
if (is_true(bool_val)) {
if (cache.exclusive) {
ERRMSG("Cache cannot be both inclusive AND exclusive.\n");
return false;
}
cache.inclusive = true;
} else {
cache.inclusive = false;
}
} else if (param == "exclusive") {
// Is the cache exclusive of its children.
std::string bool_val;
if (!(*fin_ >> bool_val)) {
ERRMSG("Error reading exclusive cache policy from "
"the configuration file\n");
return false;
}
if (is_true(bool_val)) {
if (cache.inclusive) {
ERRMSG("Cache cannot be both inclusive AND exclusive.\n");
return false;
}
cache.exclusive = true;
} else {
cache.exclusive = false;
}
} else if (param == "parent") {
// Name of the cache's parent. LLC's parent is main memory
// (CACHE_PARENT_MEMORY).
Expand Down
3 changes: 3 additions & 0 deletions clients/drcachesim/reader/config_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct cache_params_t {
, size(0)
, assoc(0)
, inclusive(false)
, exclusive(false)
, parent(CACHE_PARENT_MEMORY)
, replace_policy(REPLACE_POLICY_LRU)
, prefetcher(PREFETCH_POLICY_NONE)
Expand All @@ -79,6 +80,8 @@ struct cache_params_t {
unsigned int assoc;
// Is the cache inclusive of its children.
bool inclusive;
// Is the cache exclusive of its children.
bool exclusive;
// Name of the cache's parent. LLC's parent is main memory
// (CACHE_PARENT_MEMORY).
std::string parent;
Expand Down
9 changes: 5 additions & 4 deletions clients/drcachesim/simulator/cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ class snoop_filter_t;

bool
cache_t::init(int associativity, int line_size, int total_size, caching_device_t *parent,
caching_device_stats_t *stats, prefetcher_t *prefetcher, bool inclusive,
bool coherent_cache, int id, snoop_filter_t *snoop_filter,
caching_device_stats_t *stats, prefetcher_t *prefetcher,
cache_inclusion_policy_t inclusion_policy, bool coherent_cache, int id,
snoop_filter_t *snoop_filter,
const std::vector<caching_device_t *> &children)
{
// Check line_size to avoid divide-by-0.
Expand All @@ -64,8 +65,8 @@ cache_t::init(int associativity, int line_size, int total_size, caching_device_t
int num_lines = total_size / line_size;

return caching_device_t::init(associativity, line_size, num_lines, parent, stats,
prefetcher, inclusive, coherent_cache, id, snoop_filter,
children);
prefetcher, inclusion_policy, coherent_cache, id,
snoop_filter, children);
}

void
Expand Down
4 changes: 3 additions & 1 deletion clients/drcachesim/simulator/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ class cache_t : public caching_device_t {
bool
init(int associativity, int line_size, int total_size, caching_device_t *parent,
caching_device_stats_t *stats, prefetcher_t *prefetcher = nullptr,
bool inclusive = false, bool coherent_cache = false, int id_ = -1,
cache_inclusion_policy_t inclusion_policy =
cache_inclusion_policy_t::NON_INC_NON_EXC,
bool coherent_cache = false, int id_ = -1,
snoop_filter_t *snoop_filter_ = nullptr,
const std::vector<caching_device_t *> &children = {}) override;
void
Expand Down
6 changes: 3 additions & 3 deletions clients/drcachesim/simulator/cache_fifo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ namespace drmemtrace {
bool
cache_fifo_t::init(int associativity, int block_size, int total_size,
caching_device_t *parent, caching_device_stats_t *stats,
prefetcher_t *prefetcher, bool inclusive, bool coherent_cache, int id,
snoop_filter_t *snoop_filter,
prefetcher_t *prefetcher, cache_inclusion_policy_t inclusion_policy,
bool coherent_cache, int id, snoop_filter_t *snoop_filter,
const std::vector<caching_device_t *> &children)
{
// Works in the same way as the base class,
// except that the counters are initialized in a different way.

bool ret_val =
cache_t::init(associativity, block_size, total_size, parent, stats, prefetcher,
inclusive, coherent_cache, id, snoop_filter, children);
inclusion_policy, coherent_cache, id, snoop_filter, children);
if (ret_val == false)
return false;

Expand Down
4 changes: 3 additions & 1 deletion clients/drcachesim/simulator/cache_fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ class cache_fifo_t : public cache_t {
bool
init(int associativity, int line_size, int total_size, caching_device_t *parent,
caching_device_stats_t *stats, prefetcher_t *prefetcher = nullptr,
bool inclusive = false, bool coherent_cache = false, int id_ = -1,
cache_inclusion_policy_t inclusion_policy =
cache_inclusion_policy_t::NON_INC_NON_EXC,
bool coherent_cache = false, int id_ = -1,
snoop_filter_t *snoop_filter_ = nullptr,
const std::vector<caching_device_t *> &children = {}) override;

Expand Down
6 changes: 3 additions & 3 deletions clients/drcachesim/simulator/cache_lru.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ namespace drmemtrace {
bool
cache_lru_t::init(int associativity, int block_size, int total_size,
caching_device_t *parent, caching_device_stats_t *stats,
prefetcher_t *prefetcher, bool inclusive, bool coherent_cache, int id,
snoop_filter_t *snoop_filter,
prefetcher_t *prefetcher, cache_inclusion_policy_t inclusion_policy,
bool coherent_cache, int id, snoop_filter_t *snoop_filter,
const std::vector<caching_device_t *> &children)
{
// Works in the same way as the base class,
// except that the counters are initialized in a different way.

bool ret_val =
cache_t::init(associativity, block_size, total_size, parent, stats, prefetcher,
inclusive, coherent_cache, id, snoop_filter, children);
inclusion_policy, coherent_cache, id, snoop_filter, children);
if (ret_val == false)
return false;

Expand Down
4 changes: 3 additions & 1 deletion clients/drcachesim/simulator/cache_lru.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ class cache_lru_t : public cache_t {
bool
init(int associativity, int line_size, int total_size, caching_device_t *parent,
caching_device_stats_t *stats, prefetcher_t *prefetcher = nullptr,
bool inclusive = false, bool coherent_cache = false, int id_ = -1,
cache_inclusion_policy_t inclusion_policy =
cache_inclusion_policy_t::NON_INC_NON_EXC,
bool coherent_cache = false, int id_ = -1,
snoop_filter_t *snoop_filter_ = nullptr,
const std::vector<caching_device_t *> &children = {}) override;
std::string
Expand Down
39 changes: 34 additions & 5 deletions clients/drcachesim/simulator/cache_simulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,17 +159,17 @@ cache_simulator_t::cache_simulator_t(const cache_simulator_knobs_t &knobs)
knobs_.L1I_assoc, (int)knobs_.line_size, (int)knobs_.L1I_size, llc,
new cache_stats_t((int)knobs_.line_size, "", warmup_enabled_,
knobs_.model_coherence),
nullptr /*prefetcher*/, false /*inclusive*/, knobs_.model_coherence,
2 * i, snoop_filter_) ||
nullptr /*prefetcher*/, cache_inclusion_policy_t::NON_INC_NON_EXC,
knobs_.model_coherence, 2 * i, snoop_filter_) ||
!l1_dcaches_[i]->init(
knobs_.L1D_assoc, (int)knobs_.line_size, (int)knobs_.L1D_size, llc,
new cache_stats_t((int)knobs_.line_size, "", warmup_enabled_,
knobs_.model_coherence),
knobs_.data_prefetcher == PREFETCH_POLICY_NEXTLINE
? new prefetcher_t((int)knobs_.line_size)
: nullptr,
false /*inclusive*/, knobs_.model_coherence, (2 * i) + 1,
snoop_filter_)) {
cache_inclusion_policy_t::NON_INC_NON_EXC, knobs_.model_coherence,
(2 * i) + 1, snoop_filter_)) {
error_string_ = "Usage error: failed to initialize L1 caches. Ensure sizes "
"divided by associativities are powers of 2 "
"and that the total sizes are multiples of the line size.";
Expand Down Expand Up @@ -329,14 +329,18 @@ cache_simulator_t::cache_simulator_t(std::istream *config_file)
bool is_coherent_ = knobs_.model_coherence &&
(non_coherent_caches_.find(cache_name) == non_coherent_caches_.end());

cache_inclusion_policy_t inclusion_policy = cache_config.inclusive
? cache_inclusion_policy_t::INCLUSIVE
: cache_config.exclusive ? cache_inclusion_policy_t::EXCLUSIVE
: cache_inclusion_policy_t::NON_INC_NON_EXC;
if (!cache->init((int)cache_config.assoc, (int)knobs_.line_size,
(int)cache_config.size, parent_,
new cache_stats_t((int)knobs_.line_size, cache_config.miss_file,
warmup_enabled_, is_coherent_),
cache_config.prefetcher == PREFETCH_POLICY_NEXTLINE
? new prefetcher_t((int)knobs_.line_size)
: nullptr,
cache_config.inclusive, is_coherent_, is_snooped ? snoop_id : -1,
inclusion_policy, is_coherent_, is_snooped ? snoop_id : -1,
is_snooped ? snoop_filter_ : nullptr, children)) {
error_string_ = "Usage error: failed to initialize the cache " + cache_name;
success_ = false;
Expand Down Expand Up @@ -684,5 +688,30 @@ cache_simulator_t::create_cache(const std::string &name, const std::string &poli
return NULL;
}

// Access snoop filter stats.
int64_t
cache_simulator_t::get_num_snooped_caches(void)
{
return (snoop_filter_ == nullptr) ? 0 : snoop_filter_->get_num_snooped_caches();
}

int64_t
cache_simulator_t::get_num_snoop_writes(void)
{
return (snoop_filter_ == nullptr) ? 0 : snoop_filter_->get_num_writes();
}

int64_t
cache_simulator_t::get_num_snoop_writebacks(void)
{
return (snoop_filter_ == nullptr) ? 0 : snoop_filter_->get_num_writebacks();
}

int64_t
cache_simulator_t::get_num_snoop_invalidates(void)
{
return (snoop_filter_ == nullptr) ? 0 : snoop_filter_->get_num_invalidates();
}

} // namespace drmemtrace
} // namespace dynamorio
12 changes: 12 additions & 0 deletions clients/drcachesim/simulator/cache_simulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ class cache_simulator_t : public simulator_t {
get_cache_metric(metric_name_t metric, unsigned level, unsigned core = 0,
cache_split_t split = cache_split_t::DATA) const;

// Access snoop filter stats for coherent caches.
// These are not per-cache metrics so it doesn't make sense to access them
// through get_cache_metric().
int64_t
get_num_snooped_caches(void);
int64_t
get_num_snoop_writes(void);
int64_t
get_num_snoop_writebacks(void);
int64_t
get_num_snoop_invalidates(void);

// Exposed to make it easy to test
bool
check_warmed_up();
Expand Down
Loading

0 comments on commit 365b1a1

Please sign in to comment.