gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
associative_cache.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024-2025 Arm Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2024 Pranith Kumar
15 * Copyright (c) 2018 Metempsy Technology Consulting
16 * All rights reserved
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#ifndef __BASE_CACHE_ASSOCIATIVE_CACHE_HH__
43#define __BASE_CACHE_ASSOCIATIVE_CACHE_HH__
44
45#include <string_view>
46#include <type_traits>
47#include <vector>
48
50#include "base/intmath.hh"
51#include "base/logging.hh"
52#include "base/named.hh"
53#include "base/types.hh"
57
58namespace gem5
59{
60
61template <typename Entry>
62class AssociativeCache : public Named
63{
64 protected:
65
66 static_assert(std::is_base_of_v<ReplaceableEntry, Entry>,
67 "Entry should be derived from ReplaceableEntry");
68
70 typedef typename Entry::IndexingPolicy IndexingPolicy;
71 typedef typename Entry::KeyType KeyType;
72
75
78
81
84
85 const ::gem5::debug::SimpleFlag* debugFlag = nullptr;
86
87 private:
88
89 void
90 initParams(size_t _num_entries, size_t _assoc)
91 {
92 fatal_if((_num_entries % _assoc) != 0, "The number of entries of an "
93 "AssociativeCache<> must be a multiple of its associativity");
94 for (auto entry_idx = 0; entry_idx < _num_entries; entry_idx++) {
95 Entry *entry = &entries[entry_idx];
96 indexingPolicy->setEntry(entry, entry_idx);
97 entry->replacementData = replPolicy->instantiateEntry();
98 }
99 }
100
101 public:
102
106 AssociativeCache(std::string_view name) : Named(name) {}
107
117 AssociativeCache(std::string_view name, const size_t num_entries,
118 const size_t associativity_,
119 BaseReplacementPolicy *repl_policy,
120 IndexingPolicy *indexing_policy,
121 Entry const &init_val = Entry())
122 : Named(name),
123 associativity(associativity_),
124 replPolicy(repl_policy),
125 indexingPolicy(indexing_policy),
126 entries(num_entries, init_val),
127 debugFlag(nullptr)
128 {
129 initParams(num_entries, associativity);
130 }
131
135 ~AssociativeCache() = default;
136
142
146 void
148 {
149 for (auto &entry : entries) {
150 invalidate(&entry);
151 }
152 }
153
154 void
155 init(const size_t num_entries,
156 const size_t associativity_,
157 BaseReplacementPolicy *_repl_policy,
158 IndexingPolicy *_indexing_policy,
159 Entry const &init_val = Entry())
160 {
161 associativity = associativity_;
162 replPolicy = _repl_policy;
163 indexingPolicy = _indexing_policy;
164 entries.resize(num_entries, init_val);
165
166 initParams(num_entries, associativity);
167 }
168
169 void
170 setDebugFlag(const ::gem5::debug::SimpleFlag& flag)
171 {
172 debugFlag = &flag;
173 }
174
181 virtual Entry*
183 {
184 auto entry = findEntry(key);
185
186 if (entry) {
187 accessEntry(entry);
188 }
189
190 return entry;
191 }
192
197 virtual void
198 accessEntry(Entry *entry)
199 {
200 if (debugFlag && debugFlag->tracing()) {
202 curTick(), name(), debugFlag->name(),
203 "Accessing entry: %s\n", entry->print());
204 }
205
206
207 replPolicy->touch(entry->replacementData);
208 }
209
216 virtual Entry*
217 findEntry(const KeyType &key) const
218 {
219 auto candidates = indexingPolicy->getPossibleEntries(key);
220
221 for (auto candidate : candidates) {
222 Entry *entry = static_cast<Entry*>(candidate);
223 if (entry->match(key)) {
224 return entry;
225 }
226 }
227
228 return nullptr;
229 }
230
236 virtual Entry*
237 findVictim(const KeyType &key)
238 {
239 auto candidates = indexingPolicy->getPossibleEntries(key);
240
241 auto victim = static_cast<Entry*>(replPolicy->getVictim(candidates));
242
243 if (debugFlag && debugFlag->tracing() && victim->isValid()) {
245 curTick(), name(), debugFlag->name(),
246 "Replacing entry: %s\n", victim->print());
247 }
248
249 invalidate(victim);
250
251 return victim;
252 }
253
259 virtual void
260 invalidate(Entry *entry)
261 {
262 entry->invalidate();
263 replPolicy->invalidate(entry->replacementData);
264 }
265
271 virtual void
272 insertEntry(const KeyType &key, Entry *entry)
273 {
274 if (debugFlag && debugFlag->tracing()) {
276 curTick(), name(), debugFlag->name(),
277 "Inserting entry: %s\n", entry->print());
278 }
279
280 entry->insert(key);
281 replPolicy->reset(entry->replacementData);
282 }
283
291 getPossibleEntries(const KeyType &key) const
292 {
293 std::vector<ReplaceableEntry *> selected_entries =
294 indexingPolicy->getPossibleEntries(key);
295
297
298 std::transform(selected_entries.begin(), selected_entries.end(),
299 std::back_inserter(entries), [](auto &entry) {
300 return static_cast<Entry *>(entry);
301 });
302
303 return entries;
304 }
305
309
316 {
317 return entries.begin();
318 }
319
327 {
328 return entries.end();
329 }
330
336 begin() const
337 {
338 return entries.begin();
339 }
340
347 end() const
348 {
349 return entries.end();
350 }
351};
352
353}
354
355#endif
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
void clear()
Clear the entries in the cache.
replacement_policy::Base BaseReplacementPolicy
typename std::vector< Entry >::iterator iterator
typename std::vector< Entry >::const_iterator const_iterator
Iterator types.
const ::gem5::debug::SimpleFlag * debugFlag
Entry::IndexingPolicy IndexingPolicy
iterator begin()
Returns an iterator to the first entry of the dictionary.
virtual Entry * findVictim(const KeyType &key)
Find a victim to be replaced.
virtual Entry * findEntry(const KeyType &key) const
Find an entry within the set.
iterator end()
Returns an iterator pointing to the end of the the dictionary (placeholder element,...
~AssociativeCache()=default
Default destructor.
void initParams(size_t _num_entries, size_t _assoc)
const_iterator end() const
Returns an iterator pointing to the end of the the dictionary (placeholder element,...
AssociativeCache & operator=(const AssociativeCache &)=delete
virtual void insertEntry(const KeyType &key, Entry *entry)
Indicate that an entry has just been inserted.
void init(const size_t num_entries, const size_t associativity_, BaseReplacementPolicy *_repl_policy, IndexingPolicy *_indexing_policy, Entry const &init_val=Entry())
std::vector< Entry * > getPossibleEntries(const KeyType &key) const
Find the set of entries that could be replaced given that we want to add a new entry with the provide...
AssociativeCache(const AssociativeCache &)=delete
Disable copy and assignment.
virtual Entry * accessEntry(const KeyType &key)
Do an access to the entry if it exists.
virtual void invalidate(Entry *entry)
Invalidate an entry and its respective replacement data.
virtual void accessEntry(Entry *entry)
Update the replacement information for an entry.
const_iterator begin() const
Returns an iterator to the first entry of the dictionary.
void setDebugFlag(const ::gem5::debug::SimpleFlag &flag)
AssociativeCache(std::string_view name, const size_t num_entries, const size_t associativity_, BaseReplacementPolicy *repl_policy, IndexingPolicy *indexing_policy, Entry const &init_val=Entry())
Public constructor.
AssociativeCache(std::string_view name)
Empty constructor - need to call init() later with all args.
Named(std::string_view name_)
Definition named.hh:57
virtual std::string name() const
Definition named.hh:60
A common base class of cache replacement policy objects.
Definition base.hh:55
void dprintf_flag(Tick when, const std::string &name, const std::string &flag, const char *fmt, const Args &...args)
Log a single message with a flag prefix.
Definition trace.hh:93
STL vector class.
Definition stl.hh:37
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:268
Declaration of a common framework for indexing policies.
Logger * getDebugLogger()
Get the current global debug logger.
Definition trace.cc:68
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46

Generated on Mon May 26 2025 09:19:06 for gem5 by doxygen 1.13.2