diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2013-02-15 00:25:54 -0800 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2013-02-15 00:25:54 -0800 |
commit | 290c702c0f70973d9a34f837ca9b71a5765a81c6 (patch) | |
tree | 954d284fa244c95edeced58793c4eb61343f9632 /riscv/cachesim.h | |
parent | 3e4e4191f40f8eab3eae871aa01cfb97d8fcf779 (diff) | |
download | spike-290c702c0f70973d9a34f837ca9b71a5765a81c6.zip spike-290c702c0f70973d9a34f837ca9b71a5765a81c6.tar.gz spike-290c702c0f70973d9a34f837ca9b71a5765a81c6.tar.bz2 |
specialize fully-associative caches
the dumb linear search of a set's tag array was far too slow
Diffstat (limited to 'riscv/cachesim.h')
-rw-r--r-- | riscv/cachesim.h | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/riscv/cachesim.h b/riscv/cachesim.h index d4f4fb4..d6f5946 100644 --- a/riscv/cachesim.h +++ b/riscv/cachesim.h @@ -4,6 +4,7 @@ #include "memtracer.h" #include <cstring> #include <string> +#include <map> #include <stdint.h> class lfsr_t @@ -19,7 +20,6 @@ class lfsr_t class cache_sim_t { public: - cache_sim_t(const char* config, const char* name); cache_sim_t(size_t sets, size_t ways, size_t linesz, const char* name); cache_sim_t(const cache_sim_t& rhs); ~cache_sim_t(); @@ -28,7 +28,15 @@ class cache_sim_t void print_stats(); void set_miss_handler(cache_sim_t* mh) { miss_handler = mh; } - private: + static cache_sim_t* construct(const char* config, const char* name); + + protected: + static const uint64_t VALID = 1ULL << 63; + static const uint64_t DIRTY = 1ULL << 62; + + virtual uint64_t* check_tag(uint64_t addr); + virtual uint64_t victimize(uint64_t addr); + lfsr_t lfsr; cache_sim_t* miss_handler; @@ -49,53 +57,65 @@ class cache_sim_t std::string name; - static const uint64_t VALID = 1ULL << 63; - static const uint64_t DIRTY = 1ULL << 62; - void init(); }; -class unified_cache_sim_t : public memtracer_t +class fa_cache_sim_t : public cache_sim_t { public: - unified_cache_sim_t(const char* config) : cache(config, "U$") {} - bool interested_in_range(size_t begin, size_t end, bool store, bool fetch) + fa_cache_sim_t(size_t ways, size_t linesz, const char* name); + uint64_t* check_tag(uint64_t addr); + uint64_t victimize(uint64_t addr); + private: + static bool cmp(uint64_t a, uint64_t b); + std::map<uint64_t, uint64_t> tags; +}; + +class cache_memtracer_t : public memtracer_t +{ + public: + cache_memtracer_t(const char* config, const char* name) { - return true; + cache = cache_sim_t::construct(config, name); } - void trace(uint64_t addr, size_t bytes, bool store, bool fetch) + ~cache_memtracer_t() { - cache.access(addr, bytes, store); + delete cache; } - private: - cache_sim_t cache; + void set_miss_handler(cache_sim_t* mh) + { + cache->set_miss_handler(mh); + } + + protected: + cache_sim_t* cache; }; -class icache_sim_t : public memtracer_t, public cache_sim_t +class icache_sim_t : public cache_memtracer_t { public: - icache_sim_t(const char* config) : cache_sim_t(config, "I$") {} - bool interested_in_range(size_t begin, size_t end, bool store, bool fetch) + icache_sim_t(const char* config) : cache_memtracer_t(config, "I$") {} + bool interested_in_range(uint64_t begin, uint64_t end, bool store, bool fetch) { return fetch; } void trace(uint64_t addr, size_t bytes, bool store, bool fetch) { - if (fetch) access(addr, bytes, false); + if (fetch) cache->access(addr, bytes, false); } }; -class dcache_sim_t : public memtracer_t, public cache_sim_t +class dcache_sim_t : public cache_memtracer_t { public: - dcache_sim_t(const char* config) : cache_sim_t(config, "D$") {} - bool interested_in_range(size_t begin, size_t end, bool store, bool fetch) + dcache_sim_t(const char* config) : cache_memtracer_t(config, "D$") {} + bool interested_in_range(uint64_t begin, uint64_t end, bool store, bool fetch) { return !fetch; } void trace(uint64_t addr, size_t bytes, bool store, bool fetch) { - if (!fetch) access(addr, bytes, store); + if (!fetch) cache->access(addr, bytes, false); } }; |