6 cache_sim_t::cache_sim_t(size_t _sets
, size_t _ways
, size_t _linesz
, const char* _name
)
7 : sets(_sets
), ways(_ways
), linesz(_linesz
), name(_name
)
14 std::cerr
<< "Cache configurations must be of the form" << std::endl
;
15 std::cerr
<< " sets:ways:blocksize" << std::endl
;
16 std::cerr
<< "where sets, ways, and blocksize are positive integers, with" << std::endl
;
17 std::cerr
<< "sets and blocksize both powers of two and blocksize at least 8." << std::endl
;
21 cache_sim_t::cache_sim_t(const char* config
, const char* _name
)
24 const char* wp
= strchr(config
, ':');
26 const char* bp
= strchr(wp
, ':');
29 sets
= atoi(std::string(config
, wp
).c_str());
30 ways
= atoi(std::string(wp
, bp
).c_str());
36 void cache_sim_t::init()
38 if(sets
== 0 || (sets
& (sets
-1)))
40 if(linesz
< 8 || (linesz
& (linesz
-1)))
44 for (size_t x
= linesz
; x
; x
>>= 1)
47 tags
= new uint64_t[sets
*ways
]();
59 cache_sim_t::cache_sim_t(const cache_sim_t
& rhs
)
60 : sets(rhs
.sets
), ways(rhs
.ways
), linesz(rhs
.linesz
),
61 idx_shift(rhs
.idx_shift
), name(rhs
.name
)
63 tags
= new uint64_t[sets
*ways
];
64 memcpy(tags
, rhs
.tags
, sets
*ways
*sizeof(uint64_t));
67 cache_sim_t::~cache_sim_t()
73 void cache_sim_t::print_stats()
75 if(read_accesses
+ write_accesses
== 0)
78 float mr
= 100.0f
*(read_misses
+write_misses
)/(read_accesses
+write_accesses
);
80 std::cout
<< std::setprecision(3) << std::fixed
;
81 std::cout
<< name
<< " ";
82 std::cout
<< "Bytes Read: " << bytes_read
<< std::endl
;
83 std::cout
<< name
<< " ";
84 std::cout
<< "Bytes Written: " << bytes_written
<< std::endl
;
85 std::cout
<< name
<< " ";
86 std::cout
<< "Read Accesses: " << read_accesses
<< std::endl
;
87 std::cout
<< name
<< " ";
88 std::cout
<< "Write Accesses: " << write_accesses
<< std::endl
;
89 std::cout
<< name
<< " ";
90 std::cout
<< "Read Misses: " << read_misses
<< std::endl
;
91 std::cout
<< name
<< " ";
92 std::cout
<< "Write Misses: " << write_misses
<< std::endl
;
93 std::cout
<< name
<< " ";
94 std::cout
<< "Writebacks: " << writebacks
<< std::endl
;
95 std::cout
<< name
<< " ";
96 std::cout
<< "Miss Rate: " << mr
<< '%' << std::endl
;
99 void cache_sim_t::access(uint64_t addr
, size_t bytes
, bool store
)
101 store
? write_accesses
++ : read_accesses
++;
102 (store
? bytes_written
: bytes_read
) += bytes
;
104 size_t idx
= (addr
>> idx_shift
) & (sets
-1);
105 size_t tag
= (addr
>> idx_shift
) | VALID
;
106 size_t* set_tags
= &tags
[idx
*ways
];
108 for(size_t i
= 0; i
< ways
; i
++)
110 if(tag
== (set_tags
[i
] & ~DIRTY
)) // hit
113 set_tags
[i
] |= DIRTY
;
118 store
? write_misses
++ : read_misses
++;
120 size_t way
= lfsr
.next() % ways
;
121 if((set_tags
[way
] & (VALID
| DIRTY
)) == (VALID
| DIRTY
))
123 uint64_t dirty_addr
= (set_tags
[way
] & ~(VALID
| DIRTY
)) << idx_shift
;
124 if (miss_handler
) miss_handler
->access(dirty_addr
, linesz
, true);
127 if (miss_handler
) miss_handler
->access(addr
& ~(linesz
-1), linesz
, false);
128 set_tags
[way
] = tag
| (store
? DIRTY
: 0);