gem5 v24.0.0.0
Loading...
Searching...
No Matches
fa_lru.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023-2024 ARM Limited
3 * Copyright (c) 2018 Inria
4 * Copyright (c) 2013,2016-2018 ARM Limited
5 * All rights reserved.
6 *
7 * The license below extends only to copyright in the software and shall
8 * not be construed as granting a license to any other intellectual
9 * property including but not limited to intellectual property relating
10 * to a hardware implementation of the functionality of the software
11 * licensed hereunder. You may use the software subject to the license
12 * terms below provided that you ensure that this notice is replicated
13 * unmodified and in its entirety in all distributions of the software,
14 * modified or unmodified, in source code or in binary form.
15 *
16 * Copyright (c) 2003-2005 The Regents of The University of Michigan
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are
21 * met: redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer;
23 * redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution;
26 * neither the name of the copyright holders nor the names of its
27 * contributors may be used to endorse or promote products derived from
28 * this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 */
42
49
50#include <cassert>
51#include <sstream>
52
53#include "base/compiler.hh"
54#include "base/intmath.hh"
55#include "base/logging.hh"
56#include "mem/cache/base.hh"
58
59namespace gem5
60{
61
62std::string
64{
65 return csprintf("%s inCachesMask: %#x", CacheBlk::print(), inCachesMask);
66}
67
69 : BaseTags(p),
70
71 cacheTracking(p.min_tracked_cache_size, size, blkSize, this)
72{
73 if (!isPowerOf2(blkSize))
74 fatal("cache block size (in bytes) `%d' must be a power of two",
75 blkSize);
76 if (!isPowerOf2(size))
77 fatal("Cache Size must be power of 2 for now");
79 fatal("Cannot use Cache Partitioning Policies with FALRU");
80
81 blks = new FALRUBlk[numBlocks];
82}
83
85{
86 delete[] blks;
87}
88
89void
91{
92 head = &(blks[0]);
93 head->prev = nullptr;
94 head->next = &(blks[1]);
95 head->setPosition(0, 0);
96 head->data = &dataBlks[0];
97
98 for (unsigned i = 1; i < numBlocks - 1; i++) {
99 blks[i].prev = &(blks[i-1]);
100 blks[i].next = &(blks[i+1]);
101 blks[i].setPosition(0, i);
102
103 // Associate a data chunk to the block
105 }
106
107 tail = &(blks[numBlocks - 1]);
108 tail->prev = &(blks[numBlocks - 2]);
109 tail->next = nullptr;
110 tail->setPosition(0, numBlocks - 1);
111 tail->data = &dataBlks[(numBlocks - 1) * blkSize];
112
114}
115
116void
118{
119 // Erase block entry reference in the hash table
120 [[maybe_unused]] auto num_erased =
121 tagHash.erase(std::make_pair(blk->getTag(), blk->isSecure()));
122
123 // Sanity check; only one block reference should be erased
124 assert(num_erased == 1);
125
126 // Invalidate block entry. Must be done after the hash is erased
128
129 // Decrease the number of tags in use
131
132 // Move the block to the tail to make it the next victim
133 moveToTail((FALRUBlk*)blk);
134}
135
138{
139 return accessBlock(pkt, lat, 0);
140}
141
144 CachesMask *in_caches_mask)
145{
146 CachesMask mask = 0;
147 FALRUBlk* blk =
148 static_cast<FALRUBlk*>(findBlock(pkt->getAddr(), pkt->isSecure()));
149
150 // If a cache hit
151 if (blk && blk->isValid()) {
152 mask = blk->inCachesMask;
153
154 moveToHead(blk);
155 }
156
157 if (in_caches_mask) {
158 *in_caches_mask = mask;
159 }
160
162
163 // The tag lookup latency is the same for a hit or a miss
164 lat = lookupLatency;
165
166 return blk;
167}
168
170FALRU::findBlock(Addr addr, bool is_secure) const
171{
172 FALRUBlk* blk = nullptr;
173
174 Addr tag = extractTag(addr);
175 auto iter = tagHash.find(std::make_pair(tag, is_secure));
176 if (iter != tagHash.end()) {
177 blk = (*iter).second;
178 }
179
180 if (blk && blk->isValid()) {
181 assert(blk->getTag() == tag);
182 assert(blk->isSecure() == is_secure);
183 }
184
185 return blk;
186}
187
190{
191 assert(set == 0);
192 return &blks[way];
193}
194
196FALRU::findVictim(Addr addr, const bool is_secure, const std::size_t size,
197 std::vector<CacheBlk*>& evict_blks,
198 const uint64_t partition_id)
199{
200 // The victim is always stored on the tail for the FALRU
201 FALRUBlk* victim = tail;
202
203 // There is only one eviction for this replacement
204 evict_blks.push_back(victim);
205
206 return victim;
207}
208
209void
211{
212 FALRUBlk* falruBlk = static_cast<FALRUBlk*>(blk);
213
214 // Make sure block is not present in the cache
215 assert(falruBlk->inCachesMask == 0);
216
217 // Do common block insertion functionality
218 BaseTags::insertBlock(pkt, blk);
219
220 // Increment tag counter
222
223 // New block is the MRU
224 moveToHead(falruBlk);
225
226 // Insert new block in the hash table
227 tagHash[std::make_pair(blk->getTag(), blk->isSecure())] = falruBlk;
228}
229
230void
232{
233 panic("Moving blocks in FALRU has not been implemented");
234}
235
236void
238{
239 // If block is not already head, do the moving
240 if (blk != head) {
242 // If block is tail, set previous block as new tail
243 if (blk == tail){
244 assert(blk->next == nullptr);
245 tail = blk->prev;
246 tail->next = nullptr;
247 // Inform block's surrounding blocks that it has been moved
248 } else {
249 blk->prev->next = blk->next;
250 blk->next->prev = blk->prev;
251 }
252
253 // Swap pointers
254 blk->next = head;
255 blk->prev = nullptr;
256 head->prev = blk;
257 head = blk;
258
260 }
261}
262
263void
265{
266 // If block is not already tail, do the moving
267 if (blk != tail) {
269 // If block is head, set next block as new head
270 if (blk == head){
271 assert(blk->prev == nullptr);
272 head = blk->next;
273 head->prev = nullptr;
274 // Inform block's surrounding blocks that it has been moved
275 } else {
276 blk->prev->next = blk->next;
277 blk->next->prev = blk->prev;
278 }
279
280 // Swap pointers
281 blk->prev = tail;
282 blk->next = nullptr;
283 tail->next = blk;
284 tail = blk;
285
287 }
288}
289
290void
291printSize(std::ostream &stream, size_t size)
292{
293 static const char *SIZES[] = { "B", "kB", "MB", "GB", "TB", "ZB" };
294 int div = 0;
295 while (size >= 1024 && div < (sizeof SIZES / sizeof *SIZES)) {
296 div++;
297 size >>= 10;
298 }
299 stream << size << SIZES[div];
300}
301
302FALRU::CacheTracking::CacheTracking(unsigned min_size, unsigned max_size,
303 unsigned block_size, statistics::Group *parent)
304 : statistics::Group(parent),
305 blkSize(block_size),
306 minTrackedSize(min_size),
307 numTrackedCaches(max_size > min_size ?
308 floorLog2(max_size) - floorLog2(min_size) : 0),
309 inAllCachesMask(mask(numTrackedCaches)),
310 boundaries(numTrackedCaches),
311 ADD_STAT(hits, statistics::units::Count::get(),
312 "The number of hits in each cache size."),
313 ADD_STAT(misses, statistics::units::Count::get(),
314 "The number of misses in each cache size."),
315 ADD_STAT(accesses, statistics::units::Count::get(),
316 "The number of accesses to the FA LRU cache.")
317{
319 "Not enough bits (%s) in type CachesMask type to keep "
320 "track of %d caches\n", sizeof(CachesMask),
322
323 hits
325 misses
327
328 for (unsigned i = 0; i < numTrackedCaches + 1; ++i) {
329 std::stringstream size_str;
330 printSize(size_str, minTrackedSize << i);
331 hits.subname(i, size_str.str());
332 hits.subdesc(i, "Hits in a " + size_str.str() + " cache");
333 misses.subname(i, size_str.str());
334 misses.subdesc(i, "Misses in a " + size_str.str() + " cache");
335 }
336}
337
338void
340{
341#ifdef FALRU_DEBUG
342 const FALRUBlk* blk = head;
343 unsigned curr_size = 0;
344 unsigned tracked_cache_size = minTrackedSize;
345 CachesMask in_caches_mask = inAllCachesMask;
346 int j = 0;
347
348 while (blk) {
349 panic_if(blk->inCachesMask != in_caches_mask, "Expected cache mask "
350 "%x found %x", blk->inCachesMask, in_caches_mask);
351
352 curr_size += blkSize;
353 if (curr_size == tracked_cache_size && blk != tail) {
354 panic_if(boundaries[j] != blk, "Unexpected boundary for the %d-th "
355 "cache", j);
356 tracked_cache_size <<= 1;
357 // from this point, blocks fit only in the larger caches
358 in_caches_mask &= ~(1U << j);
359 ++j;
360 }
361 blk = blk->next;
362 }
363#endif // FALRU_DEBUG
364}
365
366void
368{
369 // early exit if we are not tracking any extra caches
370 FALRUBlk* blk = numTrackedCaches ? head : nullptr;
371 unsigned curr_size = 0;
372 unsigned tracked_cache_size = minTrackedSize;
373 CachesMask in_caches_mask = inAllCachesMask;
374 int j = 0;
375
376 while (blk) {
377 blk->inCachesMask = in_caches_mask;
378
379 curr_size += blkSize;
380 if (curr_size == tracked_cache_size && blk != tail) {
381 boundaries[j] = blk;
382
383 tracked_cache_size <<= 1;
384 // from this point, blocks fit only in the larger caches
385 in_caches_mask &= ~(1U << j);
386 ++j;
387 }
388 blk = blk->next;
389 }
390}
391
392
393void
395{
396 // Get the mask of all caches, in which the block didn't fit
397 // before moving it to the head
398 CachesMask update_caches_mask = inAllCachesMask ^ blk->inCachesMask;
399
400 for (int i = 0; i < numTrackedCaches; i++) {
401 CachesMask current_cache_mask = 1U << i;
402 if (current_cache_mask & update_caches_mask) {
403 // if the ith cache didn't fit the block (before it is moved to
404 // the head), move the ith boundary 1 block closer to the
405 // MRU
406 boundaries[i]->inCachesMask &= ~current_cache_mask;
407 boundaries[i] = boundaries[i]->prev;
408 } else if (boundaries[i] == blk) {
409 // Make sure the boundary doesn't point to the block
410 // we are about to move
411 boundaries[i] = blk->prev;
412 }
413 }
414
415 // Make block reside in all caches
416 blk->inCachesMask = inAllCachesMask;
417}
418
419void
421{
422 CachesMask update_caches_mask = blk->inCachesMask;
423
424 for (int i = 0; i < numTrackedCaches; i++) {
425 CachesMask current_cache_mask = 1U << i;
426 if (current_cache_mask & update_caches_mask) {
427 // if the ith cache fitted the block (before it is moved to
428 // the tail), move the ith boundary 1 block closer to the
429 // LRU
430 boundaries[i] = boundaries[i]->next;
431 if (boundaries[i] == blk) {
432 // Make sure the boundary doesn't point to the block
433 // we are about to move
434 boundaries[i] = blk->next;
435 }
436 boundaries[i]->inCachesMask |= current_cache_mask;
437 }
438 }
439
440 // The block now fits only in the actual cache
441 blk->inCachesMask = 0;
442}
443
444void
446{
447 for (int i = 0; i < numTrackedCaches; i++) {
448 if (blk && ((1U << i) & blk->inCachesMask)) {
449 hits[i]++;
450 } else {
451 misses[i]++;
452 }
453 }
454
455 // Record stats for the actual cache too
456 if (blk && blk->isValid()) {
457 hits[numTrackedCaches]++;
458 } else {
459 misses[numTrackedCaches]++;
460 }
461
462 accesses++;
463}
464
465} // namespace gem5
A common base class of Cache tagstore objects.
Definition base.hh:74
partitioning_policy::PartitionManager * partitionManager
Partitioning manager.
Definition base.hh:92
virtual void insertBlock(const PacketPtr pkt, CacheBlk *blk)
Insert the new block into the cache and update stats.
Definition base.cc:104
const unsigned size
The size of the cache.
Definition base.hh:81
const unsigned numBlocks
the number of blocks in the cache
Definition base.hh:103
virtual void invalidate(CacheBlk *blk)
This function updates the tags when a block is invalidated.
Definition base.hh:257
gem5::BaseTags::BaseTagStats stats
std::unique_ptr< uint8_t[]> dataBlks
The data blocks, 1 per cache block.
Definition base.hh:106
const Cycles lookupLatency
The tag lookup latency of the cache.
Definition base.hh:83
const unsigned blkSize
The block size of the cache.
Definition base.hh:77
A Basic Cache block.
Definition cache_blk.hh:72
std::string print() const override
Pretty-print tag, set and way, and interpret state bits to readable form including mapping to a MOESI...
Definition cache_blk.hh:372
uint8_t * data
Contains a copy of the data in this block for easy access.
Definition cache_blk.hh:104
virtual Addr getTag() const
Get tag associated to this block.
virtual bool isValid() const
Checks if the entry is valid.
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
A fully associative cache block.
Definition fa_lru.hh:86
FALRUBlk * next
The next block in LRU order.
Definition fa_lru.hh:94
FALRUBlk * prev
The previous block in LRU order.
Definition fa_lru.hh:92
std::string print() const override
Pretty-print inCachesMask and other CacheBlk information.
Definition fa_lru.cc:63
CachesMask inCachesMask
A bit mask of the caches that fit this block.
Definition fa_lru.hh:97
void check(const FALRUBlk *head, const FALRUBlk *tail) const
Check that the tracking mechanism is in consistent state.
Definition fa_lru.cc:339
void recordAccess(FALRUBlk *blk)
Notify of a block access.
Definition fa_lru.cc:445
void init(FALRUBlk *head, FALRUBlk *tail)
Initialiaze cache blocks and the tracking mechanism.
Definition fa_lru.cc:367
void moveBlockToHead(FALRUBlk *blk)
Update boundaries as a block will be moved to the MRU.
Definition fa_lru.cc:394
void moveBlockToTail(FALRUBlk *blk)
Update boundaries as a block will be moved to the LRU.
Definition fa_lru.cc:420
const unsigned minTrackedSize
The smallest cache we are tracking.
Definition fa_lru.hh:342
CacheTracking(unsigned min_size, unsigned max_size, unsigned block_size, statistics::Group *parent)
Definition fa_lru.cc:302
const int numTrackedCaches
The number of different size caches being tracked.
Definition fa_lru.hh:344
void moveToTail(FALRUBlk *blk)
Move a cache block to the LRU position.
Definition fa_lru.cc:264
CacheBlk * accessBlock(const PacketPtr pkt, Cycles &lat, CachesMask *in_cache_mask)
Access block and update replacement data.
Definition fa_lru.cc:143
TagHash tagHash
The address hash table.
Definition fa_lru.hh:139
Addr extractTag(Addr addr) const override
Generate the tag from the addres.
Definition fa_lru.hh:244
FALRU(const Params &p)
Construct and initialize this cache tagstore.
Definition fa_lru.cc:68
ReplaceableEntry * findBlockBySetAndWay(int set, int way) const override
Find a block given set and way.
Definition fa_lru.cc:189
void moveBlock(CacheBlk *src_blk, CacheBlk *dest_blk) override
Move a block's metadata to another location decided by the replacement policy.
Definition fa_lru.cc:231
void invalidate(CacheBlk *blk) override
Invalidate a cache block.
Definition fa_lru.cc:117
void moveToHead(FALRUBlk *blk)
Move a cache block to the MRU position.
Definition fa_lru.cc:237
CacheBlk * findVictim(Addr addr, const bool is_secure, const std::size_t size, std::vector< CacheBlk * > &evict_blks, const uint64_t partition_id=0) override
Find replacement victim based on address.
Definition fa_lru.cc:196
CacheBlk * findBlock(Addr addr, bool is_secure) const override
Find the block in the cache, do not update the replacement data.
Definition fa_lru.cc:170
CacheTracking cacheTracking
Definition fa_lru.hh:369
void tagsInit() override
Initialize blocks as FALRUBlk instances.
Definition fa_lru.cc:90
FALRUBlk * tail
The LRU block.
Definition fa_lru.hh:124
FALRUParams Params
Definition fa_lru.hh:156
FALRUBlk * head
The MRU block.
Definition fa_lru.hh:122
void insertBlock(const PacketPtr pkt, CacheBlk *blk) override
Insert the new block into the cache and update replacement data.
Definition fa_lru.cc:210
FALRUBlk * blks
The cache blocks.
Definition fa_lru.hh:119
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
bool isSecure() const
Definition packet.hh:836
Addr getAddr() const
Definition packet.hh:807
A replaceable entry is a basic entry in a 2d table-like structure that needs to have replacement func...
virtual void setPosition(const uint32_t set, const uint32_t way)
Set both the set and way.
bool isSecure() const
Check if this block holds data from the secure memory space.
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
Derived & subdesc(off_type index, const std::string &desc)
Set the subfield description for the given index and marks this stat to print at the end of simulatio...
Statistics container.
Definition group.hh:93
Derived & init(size_type size)
Set this vector to have the given size.
STL vector class.
Definition stl.hh:37
Declaration of a fully associative LRU tag store.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
statistics::Vector hits
Hits in each cache.
Definition fa_lru.hh:359
statistics::Vector misses
Misses in each cache.
Definition fa_lru.hh:361
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition intmath.hh:59
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
Declares a basic cache interface BaseCache.
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
Bitfield< 0 > p
T div(T rs1, T rs2)
Definition utility.hh:192
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint32_t CachesMask
Definition fa_lru.hh:80
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
void printSize(std::ostream &stream, size_t size)
Definition fa_lru.cc:291
statistics::Average tagsInUse
Per tick average of the number of tags that hold valid data.
Definition base.hh:121

Generated on Tue Jun 18 2024 16:24:05 for gem5 by doxygen 1.11.0