Skip to content

Commit b78e765

Browse files
committed
Add MRU
1 parent 2a39517 commit b78e765

File tree

4 files changed

+178
-57
lines changed

4 files changed

+178
-57
lines changed

src/dyad/residency/fcache.cpp

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace dyad_residency {
1111
// Associative Cache Set
1212
//=============================================================================
1313

14+
// -------------------------- LRU ------------------------
1415
bool Set_LRU::lookup (const std::string& fname, id_iterator_t &it)
1516
{
1617
id_idx_t& index_id = boost::multi_index::get<id> (m_block_set);
@@ -22,10 +23,12 @@ void Set_LRU::evict (void)
2223
{ // LRU
2324
if (m_block_set.size () == 0) return;
2425
priority_idx_t& index_priority = boost::multi_index::get<priority> (m_block_set);
25-
priority_iterator_t it = index_priority.begin ();
26-
DYAD_LOG_INFO (NULL, " %s evicts %s from set %u\n", \
27-
m_level.c_str (), it->m_id.c_str (), m_id);
28-
index_priority.erase (it);
26+
if (!index_priority.empty ()) {
27+
priority_iterator_t it = index_priority.begin ();
28+
DYAD_LOG_INFO (NULL, " %s evicts %s from set %u\n", \
29+
m_level.c_str (), it->m_id.c_str (), m_id);
30+
index_priority.erase (it);
31+
}
2932
}
3033

3134
void Set_LRU::load_and_access (const std::string& fname)
@@ -91,8 +94,32 @@ std::ostream& operator<<(std::ostream& os, const Set_LRU & cc)
9194
return cc.print (os);
9295
}
9396

97+
// -------------------------- MRU ------------------------
98+
void Set_MRU::evict (void)
99+
{ // MRU
100+
if (m_block_set.size () == 0) return;
101+
priority_idx_t& index_priority = boost::multi_index::get<priority> (m_block_set);
102+
if (!index_priority.empty ()) {
103+
auto it = index_priority.end (); --it;
104+
DYAD_LOG_INFO (NULL, " %s evicts %s from set %u\n", \
105+
m_level.c_str (), it->m_id.c_str (), m_id);
106+
index_priority.erase (it);
107+
}
108+
}
94109

110+
bool Set_MRU::access (const std::string& fname)
111+
{
112+
return Set_LRU::access (fname);
113+
}
95114

115+
std::ostream& operator<<(std::ostream& os, const Set_MRU & cc)
116+
{
117+
return cc.print (os);
118+
}
119+
120+
121+
122+
// -------------------------- Prioritied ------------------------
96123
bool Set_Prioritized::lookup (const std::string& fname, id_iterator_t &it)
97124
{
98125
id_idx_t& index_id = boost::multi_index::get<id> (m_block_set);
@@ -170,4 +197,9 @@ std::ostream& Set_Prioritized::print (std::ostream &os) const
170197
return os;
171198
}
172199

200+
std::ostream& operator<<(std::ostream& os, const Set_Prioritized& cc)
201+
{
202+
return cc.print (os);
203+
}
204+
173205
} // end of namespace dyad_residency

src/dyad/residency/fcache.hpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,38 @@ class Set_LRU
119119

120120
std::ostream& operator<<(std::ostream& os, const Set_LRU & sl);
121121

122+
class Set_MRU : public Set_LRU
123+
{
124+
protected:
125+
using Set_LRU::id;
126+
using Set_LRU::priority;
127+
using Set_LRU::LRU_Blocks;
128+
using Set_LRU::id_idx_t;
129+
using Set_LRU::id_iterator_t;
130+
using Set_LRU::id_citerator_t;
131+
using Set_LRU::priority_idx_t;
132+
using Set_LRU::priority_iterator_t;
133+
using Set_LRU::priority_citerator_t;
134+
using Set_LRU::m_block_set;
135+
136+
using Set_LRU::lookup;
137+
using Set_LRU::access;
138+
using Set_LRU::load_and_access;
139+
using Set_LRU::get_priority;
140+
141+
virtual void evict (void) override;
142+
143+
public:
144+
Set_MRU (unsigned int sz, unsigned int n_sets, unsigned int id)
145+
: Set_LRU (sz, n_sets, id) {}
146+
virtual ~Set_MRU () override {}
147+
virtual bool access (const std::string& fname) override;
148+
149+
using Set_LRU::print;
150+
};
151+
152+
std::ostream& operator<<(std::ostream& os, const Set_MRU & sm);
153+
122154

123155
class Set_Prioritized : public Set_LRU
124156
{
@@ -152,17 +184,17 @@ class Set_Prioritized : public Set_LRU
152184
Prio_Blocks m_block_set;
153185

154186
virtual bool lookup (const std::string& fname, id_iterator_t &it);
155-
virtual void evict (void);
187+
virtual void evict (void) override;
156188
virtual void access (id_iterator_t &it);
157-
virtual void load_and_access (const std::string& fname);
158-
virtual unsigned int get_priority ();
189+
virtual void load_and_access (const std::string& fname) override;
190+
virtual unsigned int get_priority () override;
159191

160192
public:
161193
Set_Prioritized (unsigned int sz, unsigned int n_sets, unsigned int id)
162194
: Set_LRU (sz, n_sets, id) {}
163-
virtual ~Set_Prioritized () {}
164-
virtual bool access (const std::string& fname);
165-
virtual std::ostream& print (std::ostream &os) const;
195+
virtual ~Set_Prioritized () override {}
196+
virtual bool access (const std::string& fname) override;
197+
virtual std::ostream& print (std::ostream &os) const override;
166198
};
167199

168200
std::ostream& operator<<(std::ostream& os, const Set_Prioritized & sp);

src/dyad/residency/fcache_impl.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ template <typename Set>
7676
bool Cache<Set>::access (const std::string& fname)
7777
{
7878
//const unsigned int set_id = 0u;
79-
//const unsigned int set_id = std::stoi (fname) % m_num_sets;
80-
const unsigned int set_id = get_cache_set_id (fname);
79+
const unsigned int set_id = std::stoi (fname) % m_num_sets;
80+
//const unsigned int set_id = get_cache_set_id (fname);
8181

8282
return m_set[set_id].access (fname);
8383
}

src/dyad/residency/test_fcache.cpp

Lines changed: 102 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,79 +2,136 @@
22
#include <string>
33
#include <iostream>
44
#include <cstdlib>
5+
#include <memory>
6+
#include <type_traits>
57

6-
int main (int argc, char** argv)
8+
namespace dyad_residency
79
{
8-
using namespace dyad_residency;
910

10-
int seed = 0;
11+
enum Set_Type {Set_LRU_, Set_MRU_, Set_Prio_, Set_End_};
12+
1113

12-
if (argc > 2) {
14+
template<Set_Type V>
15+
using st = std::integral_constant<Set_Type, V>;
16+
17+
std::unique_ptr<Cache<Set_LRU>> make_cache(st<Set_LRU_>, unsigned size, unsigned ways) {
18+
return std::unique_ptr<Cache<Set_LRU>>(new Cache<Set_LRU>(size, ways));
19+
}
20+
std::unique_ptr<Cache<Set_MRU>> make_cache(st<Set_MRU_>, unsigned size, unsigned ways) {
21+
return std::unique_ptr<Cache<Set_MRU>>(new Cache<Set_MRU>(size, ways));
22+
}
23+
std::unique_ptr<Cache<Set_Prioritized>> make_cache(st<Set_Prio_>, unsigned size, unsigned ways) {
24+
return std::unique_ptr<Cache<Set_Prioritized>>(new Cache<Set_Prioritized>(size, ways));
25+
}
26+
27+
template< template<typename S> typename C, typename S>
28+
int run_cache (int seed,
29+
std::unique_ptr<C<S>>& cacheL1,
30+
std::unique_ptr<C<S>>& cacheL2,
31+
const std::vector<std::string>& acc)
32+
{
33+
bool hitL1 = false;
34+
35+
if (!cacheL1 || !cacheL2) {
36+
std::cerr << "Cannot allocate cache." << std::endl;
1337
return EXIT_FAILURE;
1438
}
15-
if (argc == 2) {
16-
seed = atoi (argv[1]);
17-
}
39+
cacheL1->set_seed (seed + 104677u);
40+
cacheL1->set_level ("L1");
41+
cacheL2->set_seed (seed + 104681u);
42+
cacheL2->set_level (" L2");
1843

19-
typedef std::vector<std::string> access;
20-
access acc; // access pattern in terms of the block index
21-
acc.push_back ("1");
22-
acc.push_back ("4");
23-
acc.push_back ("2");
24-
acc.push_back ("3");
25-
acc.push_back ("5");
26-
acc.push_back ("5");
27-
acc.push_back ("3");
28-
bool hitL1;
29-
30-
#if 1
31-
Cache<Set_LRU> cacheL1 (4, 2); // 2-way set-associative
32-
Cache<Set_LRU> cacheL2 (8, 2); // cache capacity = 8 blocks
33-
#else
34-
Cache<Set_LRU> cacheL1 (4, 0); // cache capacity = 4 blocks
35-
Cache<Set_LRU> cacheL2 (8, 0); // fully-associative
36-
#endif
37-
cacheL1.set_seed (seed + 104677u);
38-
cacheL1.set_level ("L1");
39-
cacheL2.set_seed (seed + 104681u);
40-
cacheL2.set_level (" L2");
41-
42-
std::cout << "L1 Cache size set to " << cacheL1.size () << " blocks" << std::endl;
43-
std::cout << "L2 Cache size set to " << cacheL2.size () << " blocks" << std::endl;
44+
std::cout << "L1 Cache size set to " << cacheL1->size () << " blocks" << std::endl;
45+
std::cout << "L2 Cache size set to " << cacheL2->size () << " blocks" << std::endl;
4446

4547
std::cout << "accessing block 1, 4, 2, and 3 in order" << std::endl;
46-
for (unsigned int i = 0; (i < cacheL1.size ()) && (i < acc.size ()); i++) {
47-
hitL1 = cacheL1.access (acc[i]);
48-
if (!hitL1) cacheL2.access (acc[i]);
48+
for (unsigned int i = 0; (i < cacheL1->size ()) && (i < acc.size ()); i++) {
49+
hitL1 = cacheL1->access (acc[i]);
50+
if (!hitL1) cacheL2->access (acc[i]);
4951
}
5052

5153
std::cout << "-------------------------L1----------------------------" << std::endl;
52-
std::cout << cacheL1 << std::endl;
54+
std::cout << *cacheL1 << std::endl;
5355
std::cout << "-------------------------L2----------------------------" << std::endl;
54-
std::cout << cacheL2 << std::endl;
56+
std::cout << *cacheL2 << std::endl;
5557
std::cout << "-------------------------------------------------------" << std::endl;
5658

5759
std::cout << "accessing block 5" << std::endl;
58-
hitL1 = cacheL1.access (acc[4]);
59-
if (!hitL1) cacheL2.access (acc[4]);
60+
hitL1 = cacheL1->access (acc[4]);
61+
if (!hitL1) cacheL2->access (acc[4]);
6062

6163
std::cout << "-------------------------L1----------------------------" << std::endl;
62-
std::cout << cacheL1 << std::endl;
64+
std::cout << *cacheL1 << std::endl;
6365
std::cout << "-------------------------L2----------------------------" << std::endl;
64-
std::cout << cacheL2 << std::endl;
66+
std::cout << *cacheL2 << std::endl;
6567
std::cout << "-------------------------------------------------------" << std::endl;
6668

6769
std::cout << "accessing block 1, 4, 2, 3, 5, 5, and 3 in order" << std::endl;
6870
for (unsigned int i = 0; i < acc.size (); i++) {
69-
hitL1 = cacheL1.access (acc[i]);
70-
if (!hitL1) cacheL2.access (acc[i]);
71+
hitL1 = cacheL1->access (acc[i]);
72+
if (!hitL1) cacheL2->access (acc[i]);
7173
}
7274

7375
std::cout << "-------------------------L1----------------------------" << std::endl;
74-
std::cout << cacheL1 << std::endl;
76+
std::cout << *cacheL1 << std::endl;
7577
std::cout << "-------------------------L2----------------------------" << std::endl;
76-
std::cout << cacheL2 << std::endl;
78+
std::cout << *cacheL2 << std::endl;
7779
std::cout << "-------------------------------------------------------" << std::endl;
7880

7981
return EXIT_SUCCESS;
8082
}
83+
84+
int cache_demo (const Set_Type st, int seed,
85+
unsigned sizeL1, unsigned waysL1,
86+
unsigned sizeL2, unsigned waysL2,
87+
const std::vector<std::string>& acc)
88+
{
89+
if (st == Set_LRU_) {
90+
auto cacheL1 = std::unique_ptr<Cache<Set_LRU>>(new Cache<Set_LRU> (sizeL1, waysL1));
91+
auto cacheL2 = std::unique_ptr<Cache<Set_LRU>>(new Cache<Set_LRU> (sizeL2, waysL2));
92+
return run_cache (seed, cacheL1, cacheL2, acc);
93+
} else if (st == Set_MRU_) {
94+
auto cacheL1 = std::unique_ptr<Cache<Set_MRU>>(new Cache<Set_MRU> (sizeL1, waysL1));
95+
auto cacheL2 = std::unique_ptr<Cache<Set_MRU>>(new Cache<Set_MRU> (sizeL2, waysL2));
96+
return run_cache (seed, cacheL1, cacheL2, acc);
97+
} else if (st == Set_Prio_) {
98+
auto cacheL1 = std::unique_ptr<Cache<Set_Prioritized>>(new Cache<Set_Prioritized> (sizeL1, waysL1));
99+
auto cacheL2 = std::unique_ptr<Cache<Set_Prioritized>>(new Cache<Set_Prioritized> (sizeL2, waysL2));
100+
return run_cache (seed, cacheL1, cacheL2, acc);
101+
}
102+
return EXIT_FAILURE;
103+
}
104+
105+
} // end of namespace dyad_Residency
106+
107+
108+
int main (int argc, char** argv)
109+
{
110+
using namespace dyad_residency;
111+
112+
int seed = 0;
113+
Set_Type set_type = Set_LRU_;
114+
115+
if (argc > 3) {
116+
return EXIT_FAILURE;
117+
}
118+
if (argc >= 2) {
119+
seed = atoi (argv[1]);
120+
}
121+
if (argc == 3) {
122+
int st = atoi (argv[2]);
123+
set_type = static_cast<Set_Type> (st % Set_End_);
124+
}
125+
126+
typedef std::vector<std::string> access;
127+
access acc; // access pattern in terms of the block index
128+
acc.push_back ("1");
129+
acc.push_back ("4");
130+
acc.push_back ("2");
131+
acc.push_back ("3");
132+
acc.push_back ("5");
133+
acc.push_back ("5");
134+
acc.push_back ("3");
135+
136+
return cache_demo (set_type, seed, 4, 2, 8, 2, acc);
137+
}

0 commit comments

Comments
 (0)