gem5 v24.1.0.1
Loading...
Searching...
No Matches
skewed_associative.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
35
36#include "base/bitfield.hh"
37#include "base/intmath.hh"
38#include "base/logging.hh"
40
41namespace gem5
42{
43
45 : BaseIndexingPolicy(p, p.size / p.entry_size, floorLog2(p.entry_size)),
46 msbShift(floorLog2(numSets) - 1)
47{
49 warn_once("Associativity higher than number of skewing functions. " \
50 "Expect sub-optimal skewing.\n");
51 }
52
53 // Check if set is too big to do skewing. If using big sets, rewrite
54 // skewing functions accordingly to make good use of the hashing function
55 panic_if(setShift + 2 * (msbShift + 1) > 64, "Unsuported number of bits " \
56 "for the skewing functions.");
57
58 // We must have more than two sets, otherwise the MSB and LSB are the same
59 // bit, and the xor of them will always be 0
60 fatal_if(numSets <= 2, "The number of sets must be greater than 2");
61}
62
63Addr
65{
66 // Get relevant bits
67 const uint8_t lsb = bits<Addr>(addr, 0);
68 const uint8_t msb = bits<Addr>(addr, msbShift);
69 const uint8_t xor_bit = msb ^ lsb;
70
71 // Shift-off LSB and set new MSB as xor of old LSB and MSB
72 return insertBits<Addr, uint8_t>(addr >> 1, msbShift, xor_bit);
73}
74
75Addr
77{
78 // Get relevant bits. The original MSB is one bit away on the current MSB
79 // (which is the XOR bit). The original LSB can be retrieved from inverting
80 // the xor that generated the XOR bit.
81 const uint8_t msb = bits<Addr>(addr, msbShift - 1);
82 const uint8_t xor_bit = bits<Addr>(addr, msbShift);
83 const uint8_t lsb = msb ^ xor_bit;
84
85 // Remove current MSB (XOR bit), shift left and add LSB back
86 const Addr addr_no_msb = mbits<Addr>(addr, msbShift - 1, 0);
87 return insertBits<Addr, uint8_t>(addr_no_msb << 1, 0, lsb);
88}
89
90Addr
91SkewedAssociative::skew(const Addr addr, const uint32_t way) const
92{
93 // Assume an address of size A bits can be decomposed into
94 // {addr3, addr2, addr1, addr0}, where:
95 // addr0 (M bits) = Block offset;
96 // addr1 (N bits) = Set bits in conventional cache;
97 // addr3 (A - M - 2*N bits), addr2 (N bits) = Tag bits.
98 // We use addr1 and addr2, as proposed in the original paper
99 Addr addr1 = bits<Addr>(addr, msbShift, 0);
100 const Addr addr2 = bits<Addr>(addr, 2 * (msbShift + 1) - 1, msbShift + 1);
101
102 // Select and apply skewing function for given way
103 switch (way % NUM_SKEWING_FUNCTIONS) {
104 case 0:
105 addr1 = hash(addr1) ^ hash(addr2) ^ addr2;
106 break;
107 case 1:
108 addr1 = hash(addr1) ^ hash(addr2) ^ addr1;
109 break;
110 case 2:
111 addr1 = hash(addr1) ^ dehash(addr2) ^ addr2;
112 break;
113 case 3:
114 addr1 = hash(addr1) ^ dehash(addr2) ^ addr1;
115 break;
116 case 4:
117 addr1 = dehash(addr1) ^ hash(addr2) ^ addr2;
118 break;
119 case 5:
120 addr1 = dehash(addr1) ^ hash(addr2) ^ addr1;
121 break;
122 case 6:
123 addr1 = dehash(addr1) ^ dehash(addr2) ^ addr2;
124 break;
125 case 7:
126 addr1 = dehash(addr1) ^ dehash(addr2) ^ addr1;
127 break;
128 default:
129 panic("A skewing function has not been implemented for this way.");
130 }
131
132 // If we have more than 8 ways, just pile them up on hashes. This is not
133 // the optimal solution, and can be improved by adding more skewing
134 // functions to the previous selector
135 for (uint32_t i = 0; i < way/NUM_SKEWING_FUNCTIONS; i++) {
136 addr1 = hash(addr1);
137 }
138
139 return addr1;
140}
141
142Addr
143SkewedAssociative::deskew(const Addr addr, const uint32_t way) const
144{
145 // Get relevant bits of the addr
146 Addr addr1 = bits<Addr>(addr, msbShift, 0);
147 const Addr addr2 = bits<Addr>(addr, 2 * (msbShift + 1) - 1, msbShift + 1);
148
149 // If we have more than NUM_SKEWING_FUNCTIONS ways, unpile the hashes
150 if (way >= NUM_SKEWING_FUNCTIONS) {
151 for (uint32_t i = 0; i < way/NUM_SKEWING_FUNCTIONS; i++) {
152 addr1 = dehash(addr1);
153 }
154 }
155
156 // Select and apply skewing function for given way
157 switch (way % 8) {
158 case 0:
159 return dehash(addr1 ^ hash(addr2) ^ addr2);
160 case 1:
161 addr1 = addr1 ^ hash(addr2);
162 for (int i = 0; i < msbShift; i++) {
163 addr1 = hash(addr1);
164 }
165 return addr1;
166 case 2:
167 return dehash(addr1 ^ dehash(addr2) ^ addr2);
168 case 3:
169 addr1 = addr1 ^ dehash(addr2);
170 for (int i = 0; i < msbShift; i++) {
171 addr1 = hash(addr1);
172 }
173 return addr1;
174 case 4:
175 return hash(addr1 ^ hash(addr2) ^ addr2);
176 case 5:
177 addr1 = addr1 ^ hash(addr2);
178 for (int i = 0; i <= msbShift; i++) {
179 addr1 = hash(addr1);
180 }
181 return addr1;
182 case 6:
183 return hash(addr1 ^ dehash(addr2) ^ addr2);
184 case 7:
185 addr1 = addr1 ^ dehash(addr2);
186 for (int i = 0; i <= msbShift; i++) {
187 addr1 = hash(addr1);
188 }
189 return addr1;
190 default:
191 panic("A skewing function has not been implemented for this way.");
192 }
193}
194
195uint32_t
196SkewedAssociative::extractSet(const Addr addr, const uint32_t way) const
197{
198 return skew(addr >> setShift, way) & setMask;
199}
200
201Addr
203 const ReplaceableEntry* entry) const
204{
205 const Addr addr_set = (tag << (msbShift + 1)) | entry->getSet();
206 return (tag << tagShift) |
207 ((deskew(addr_set, entry->getWay()) & setMask) << setShift);
208}
209
212{
214
215 // Parse all ways
216 for (uint32_t way = 0; way < assoc; ++way) {
217 // Apply hash to get set, and get way entry in it
218 entries.push_back(sets[extractSet(addr, way)][way]);
219 }
220
221 return entries;
222}
223
224} // namespace gem5
A common base class for indexing table locations.
Definition base.hh:73
const int tagShift
The amount to shift the address to get the tag.
Definition base.hh:106
const uint32_t numSets
The number of sets in the cache.
Definition base.hh:86
std::vector< std::vector< ReplaceableEntry * > > sets
The cache sets.
Definition base.hh:101
const unsigned setMask
Mask out all bits that aren't part of the set index.
Definition base.hh:96
const unsigned assoc
The associativity.
Definition base.hh:81
const int setShift
The amount to shift the address to get the set.
Definition base.hh:91
A replaceable entry is a basic entry in a 2d table-like structure that needs to have replacement func...
uint32_t getWay() const
Get way number.
uint32_t getSet() const
Get set number.
Addr deskew(const Addr addr, const uint32_t way) const
Address deskewing function (inverse of the skew function) of the given way.
uint32_t extractSet(const Addr addr, const uint32_t way) const
Apply a skewing function to calculate address' set given a way.
std::vector< ReplaceableEntry * > getPossibleEntries(const Addr &addr) const override
Find all possible entries for insertion and replacement of an address.
const int msbShift
The amount to shift a set index to get its MSB.
Addr regenerateAddr(const Addr &tag, const ReplaceableEntry *entry) const override
Regenerate an entry's address from its tag and assigned set and way.
Addr skew(const Addr addr, const uint32_t way) const
Address skewing function selection.
SkewedAssociativeParams Params
Convenience typedef.
const int NUM_SKEWING_FUNCTIONS
The number of skewing functions implemented.
Addr hash(const Addr addr) const
The hash function itself.
SkewedAssociative(const Params &p)
Construct and initialize this policy.
Addr dehash(const Addr addr) const
Inverse of the hash function.
STL vector class.
Definition stl.hh:37
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition intmath.hh:59
#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 panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
#define warn_once(...)
Definition logging.hh:260
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 0 > p
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 Arm Limited 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
Declaration of a skewed associative indexing policy.

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