gem5 v24.1.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
associative_cache.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 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 <type_traits>
46#include <vector>
47
49#include "base/intmath.hh"
50#include "base/logging.hh"
51#include "base/named.hh"
52#include "base/types.hh"
56
57namespace gem5
58{
59
60template <typename Entry>
61class AssociativeCache : public Named
62{
63 protected:
64
65 static_assert(std::is_base_of_v<ReplaceableEntry, Entry>,
66 "Entry should be derived from ReplaceableEntry");
67
69 typedef typename Entry::IndexingPolicy IndexingPolicy;
70 typedef typename Entry::KeyType KeyType;
71
74
77
80
83
84 const ::gem5::debug::SimpleFlag* debugFlag = nullptr;
85
86 private:
87
88 void
89 initParams(size_t _num_entries, size_t _assoc)
90 {
91 fatal_if((_num_entries % _assoc) != 0, "The number of entries of an "
92 "AssociativeCache<> must be a multiple of its associativity");
93 for (auto entry_idx = 0; entry_idx < _num_entries; entry_idx++) {
94 Entry *entry = &entries[entry_idx];
95 indexingPolicy->setEntry(entry, entry_idx);
96 entry->replacementData = replPolicy->instantiateEntry();
97 }
98 }
99
100 public:
101
105 AssociativeCache(const char *name) : Named(std::string(name)) {}
106
116 AssociativeCache(const char *name, const size_t num_entries,
117 const size_t associativity_,
118 BaseReplacementPolicy *repl_policy,
119 IndexingPolicy *indexing_policy,
120 Entry const &init_val = Entry())
121 : Named(std::string(name)),
122 associativity(associativity_),
123 replPolicy(repl_policy),
124 indexingPolicy(indexing_policy),
125 entries(num_entries, init_val),
126 debugFlag(nullptr)
127 {
128 initParams(num_entries, associativity);
129 }
130
134 ~AssociativeCache() = default;
135
141
145 void
147 {
148 for (auto &entry : entries) {
149 invalidate(&entry);
150 }
151 }
152
153 void
154 init(const size_t num_entries,
155 const size_t associativity_,
156 BaseReplacementPolicy *_repl_policy,
157 IndexingPolicy *_indexing_policy,
158 Entry const &init_val = Entry())
159 {
160 associativity = associativity_;
161 replPolicy = _repl_policy;
162 indexingPolicy = _indexing_policy;
163 entries.resize(num_entries, init_val);
164
165 initParams(num_entries, associativity);
166 }
167
168 void
169 setDebugFlag(const ::gem5::debug::SimpleFlag& flag)
170 {
171 debugFlag = &flag;
172 }
173
180 virtual Entry*
182 {
183 auto entry = findEntry(key);
184
185 if (entry) {
186 accessEntry(entry);
187 }
188
189 return entry;
190 }
191
196 virtual void
197 accessEntry(Entry *entry)
198 {
199 replPolicy->touch(entry->replacementData);
200 }
201
208 virtual Entry*
209 findEntry(const KeyType &key) const
210 {
211 auto candidates = indexingPolicy->getPossibleEntries(key);
212
213 for (auto candidate : candidates) {
214 Entry *entry = static_cast<Entry*>(candidate);
215 if (entry->match(key)) {
216 return entry;
217 }
218 }
219
220 return nullptr;
221 }
222
228 virtual Entry*
229 findVictim(const KeyType &key)
230 {
231 auto candidates = indexingPolicy->getPossibleEntries(key);
232
233 auto victim = static_cast<Entry*>(replPolicy->getVictim(candidates));
234
235 if (debugFlag && debugFlag->tracing() && victim->isValid()) {
237 curTick(), name(), debugFlag->name(),
238 "Replacing entry: %s\n", victim->print());
239 }
240
241 invalidate(victim);
242
243 return victim;
244 }
245
251 virtual void
252 invalidate(Entry *entry)
253 {
254 entry->invalidate();
255 replPolicy->invalidate(entry->replacementData);
256 }
257
263 virtual void
264 insertEntry(const KeyType &key, Entry *entry)
265 {
266 if (debugFlag && debugFlag->tracing()) {
268 curTick(), name(), debugFlag->name(),
269 "Inserting entry: %s\n", entry->print());
270 }
271
272 entry->insert(key);
273 replPolicy->reset(entry->replacementData);
274 }
275
283 getPossibleEntries(const KeyType &key) const
284 {
285 std::vector<ReplaceableEntry *> selected_entries =
286 indexingPolicy->getPossibleEntries(key);
287
289
290 std::transform(selected_entries.begin(), selected_entries.end(),
291 std::back_inserter(entries), [](auto &entry) {
292 return static_cast<Entry *>(entry);
293 });
294
295 return entries;
296 }
297
301
308 {
309 return entries.begin();
310 }
311
319 {
320 return entries.end();
321 }
322
328 begin() const
329 {
330 return entries.begin();
331 }
332
339 end() const
340 {
341 return entries.end();
342 }
343};
344
345}
346
347#endif
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
void clear()
Clear the entries in the cache.
AssociativeCache(const char *name)
Empty constructor - need to call init() later with all args.
replacement_policy::Base BaseReplacementPolicy
typename std::vector< Entry >::iterator iterator
typename std::vector< Entry >::const_iterator const_iterator
Iterator types.
size_t associativity
Associativity of the cache.
const ::gem5::debug::SimpleFlag * debugFlag
Entry::IndexingPolicy IndexingPolicy
IndexingPolicy * indexingPolicy
Indexing policy of the cache.
iterator begin()
Returns an iterator to the first entry of the dictionary.
virtual Entry * findVictim(const KeyType &key)
Find a victim to be replaced.
BaseReplacementPolicy * replPolicy
The replacement policy of the cache.
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)
std::vector< Entry > entries
The entries.
AssociativeCache(const char *name, const size_t num_entries, const size_t associativity_, BaseReplacementPolicy *repl_policy, IndexingPolicy *indexing_policy, Entry const &init_val=Entry())
Public constructor.
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)
Interface for things with names.
Definition named.hh:39
virtual std::string name() const
Definition named.hh:47
std::string name() const
Definition debug.hh:77
bool tracing() const
Definition debug.hh:80
A common base class of cache replacement policy objects.
Definition base.hh:55
virtual void invalidate(const std::shared_ptr< ReplacementData > &replacement_data)=0
Invalidate replacement data to set it as the next probable victim.
virtual void reset(const std::shared_ptr< ReplacementData > &replacement_data, const PacketPtr pkt)
Reset replacement data.
Definition base.hh:89
virtual void touch(const std::shared_ptr< ReplacementData > &replacement_data, const PacketPtr pkt)
Update replacement data.
Definition base.hh:75
virtual ReplaceableEntry * getVictim(const ReplacementCandidates &candidates) const =0
Find replacement victim among candidates.
virtual std::shared_ptr< ReplacementData > instantiateEntry()=0
Instantiate a replacement data entry.
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:236
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
Overload hash function for BasicBlockRange type.
Definition binary32.hh:81

Generated on Mon Jan 13 2025 04:28:29 for gem5 by doxygen 1.9.8