cd33ca11f58328ee3e5f26d7fbc86f33f820a858
7 cache_sim_t::cache_sim_t(size_t _sets
, size_t _ways
, size_t _linesz
, const char* _name
)
8 : sets(_sets
), ways(_ways
), linesz(_linesz
), name(_name
)
15 std::cerr
<< "Cache configurations must be of the form" << std::endl
;
16 std::cerr
<< " sets:ways:blocksize" << std::endl
;
17 std::cerr
<< "where sets, ways, and blocksize are positive integers, with" << std::endl
;
18 std::cerr
<< "sets and blocksize both powers of two and blocksize at least 8." << std::endl
;
22 cache_sim_t
* cache_sim_t::construct(const char* config
, const char* name
)
24 const char* wp
= strchr(config
, ':');
26 const char* bp
= strchr(wp
, ':');
29 size_t sets
= atoi(std::string(config
, wp
).c_str());
30 size_t ways
= atoi(std::string(wp
, bp
).c_str());
31 size_t linesz
= atoi(bp
);
33 if (ways
> 4 /* empirical */ && sets
== 1)
34 return new fa_cache_sim_t(ways
, linesz
, name
);
35 return new cache_sim_t(sets
, ways
, linesz
, name
);
38 void cache_sim_t::init()
40 if(sets
== 0 || (sets
& (sets
-1)))
42 if(linesz
< 8 || (linesz
& (linesz
-1)))
46 for (size_t x
= linesz
; x
; x
>>= 1)
49 tags
= new uint64_t[sets
*ways
]();
61 cache_sim_t::cache_sim_t(const cache_sim_t
& rhs
)
62 : sets(rhs
.sets
), ways(rhs
.ways
), linesz(rhs
.linesz
),
63 idx_shift(rhs
.idx_shift
), name(rhs
.name
)
65 tags
= new uint64_t[sets
*ways
];
66 memcpy(tags
, rhs
.tags
, sets
*ways
*sizeof(uint64_t));
69 cache_sim_t::~cache_sim_t()
75 void cache_sim_t::print_stats()
77 if(read_accesses
+ write_accesses
== 0)
80 float mr
= 100.0f
*(read_misses
+write_misses
)/(read_accesses
+write_accesses
);
82 std::cout
<< std::setprecision(3) << std::fixed
;
83 std::cout
<< name
<< " ";
84 std::cout
<< "Bytes Read: " << bytes_read
<< std::endl
;
85 std::cout
<< name
<< " ";
86 std::cout
<< "Bytes Written: " << bytes_written
<< std::endl
;
87 std::cout
<< name
<< " ";
88 std::cout
<< "Read Accesses: " << read_accesses
<< std::endl
;
89 std::cout
<< name
<< " ";
90 std::cout
<< "Write Accesses: " << write_accesses
<< std::endl
;
91 std::cout
<< name
<< " ";
92 std::cout
<< "Read Misses: " << read_misses
<< std::endl
;
93 std::cout
<< name
<< " ";
94 std::cout
<< "Write Misses: " << write_misses
<< std::endl
;
95 std::cout
<< name
<< " ";
96 std::cout
<< "Writebacks: " << writebacks
<< std::endl
;
97 std::cout
<< name
<< " ";
98 std::cout
<< "Miss Rate: " << mr
<< '%' << std::endl
;
101 uint64_t* cache_sim_t::check_tag(uint64_t addr
)
103 size_t idx
= (addr
>> idx_shift
) & (sets
-1);
104 size_t tag
= (addr
>> idx_shift
) | VALID
;
106 for (size_t i
= 0; i
< ways
; i
++)
107 if (tag
== (tags
[idx
*ways
+ i
] & ~DIRTY
))
108 return &tags
[idx
*ways
+ i
];
113 uint64_t cache_sim_t::victimize(uint64_t addr
)
115 size_t idx
= (addr
>> idx_shift
) & (sets
-1);
116 size_t way
= lfsr
.next() % ways
;
117 uint64_t victim
= tags
[idx
*ways
+ way
];
118 tags
[idx
*ways
+ way
] = (addr
>> idx_shift
) | VALID
;
122 void cache_sim_t::access(uint64_t addr
, size_t bytes
, bool store
)
124 store
? write_accesses
++ : read_accesses
++;
125 (store
? bytes_written
: bytes_read
) += bytes
;
127 uint64_t* hit_way
= check_tag(addr
);
128 if (likely(hit_way
!= NULL
))
135 store
? write_misses
++ : read_misses
++;
137 uint64_t victim
= victimize(addr
);
139 if ((victim
& (VALID
| DIRTY
)) == (VALID
| DIRTY
))
141 uint64_t dirty_addr
= (victim
& ~(VALID
| DIRTY
)) << idx_shift
;
143 miss_handler
->access(dirty_addr
, linesz
, true);
148 miss_handler
->access(addr
& ~(linesz
-1), linesz
, false);
151 *check_tag(addr
) |= DIRTY
;
154 fa_cache_sim_t::fa_cache_sim_t(size_t ways
, size_t linesz
, const char* name
)
155 : cache_sim_t(1, ways
, linesz
, name
)
159 uint64_t* fa_cache_sim_t::check_tag(uint64_t addr
)
161 auto it
= tags
.find(addr
>> idx_shift
);
162 return it
== tags
.end() ? NULL
: &it
->second
;
165 uint64_t fa_cache_sim_t::victimize(uint64_t addr
)
167 uint64_t old_tag
= 0;
168 if (tags
.size() == ways
)
170 auto it
= tags
.begin();
171 std::advance(it
, lfsr
.next() % ways
);
172 old_tag
= it
->second
;
175 tags
[addr
>> idx_shift
] = (addr
>> idx_shift
) | VALID
;