gem5 v24.0.0.0
Loading...
Searching...
No Matches
address_manager.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017-2020 Advanced Micro Devices, Inc.
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 met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
33
34#include <algorithm>
35#include <climits>
36
37#include "base/intmath.hh"
38#include "base/logging.hh"
39#include "base/random.hh"
40#include "base/trace.hh"
41
42namespace gem5
43{
44
47
48AddressManager::AddressManager(int n_atomic_locs, int n_normal_locs_per_atomic)
49 : numAtomicLocs(n_atomic_locs),
50 numLocsPerAtomic(n_normal_locs_per_atomic)
51{
52 assert(numAtomicLocs > 0 && numLocsPerAtomic > 0);
54
55 // generate random address map
57 for (Location i = 0; i < numAtomicLocs + numNormalLocs; ++i) {
58 // all addresses are sizeof(Value) (i.e., 4-byte) aligned
59 randAddressMap[i] = (Addr)((i + 128) << floorLog2(sizeof(Value)));
60 }
61
62 // randomly shuffle randAddressMap. The seed is determined by the random_mt
63 // gem5 rng. This allows for deterministic randomization.
64 std::shuffle(
65 randAddressMap.begin(),
66 randAddressMap.end(),
67 std::default_random_engine(random_mt.random<unsigned>(0,UINT_MAX))
68 );
69
70 // initialize atomic locations
71 // first and last normal location per atomic location
72 Location first, last;
73 for (Location atomic_loc = 0; atomic_loc < numAtomicLocs; ++atomic_loc) {
74 first = numAtomicLocs + numLocsPerAtomic * atomic_loc;
75 last = first + numLocsPerAtomic - 1;
76 atomicStructs.push_back(new AtomicStruct(atomic_loc, first, last));
77 }
78
79 // initialize log table
80 for (Location loc = 0; loc < numAtomicLocs + numNormalLocs; ++loc) {
81 logTable.push_back(new LastWriter());
82 }
83}
84
86{
87 for (AtomicStruct* atomic_struct : atomicStructs)
88 delete atomic_struct;
89 for (LastWriter* lw : logTable)
90 delete lw;
91}
92
93Addr
95{
96 assert(loc < numAtomicLocs + numNormalLocs && loc >= 0);
97 return randAddressMap[loc];
98}
99
102{
103 Location ret_atomic_loc = \
104 random_mt.random<unsigned long>() % numAtomicLocs;
105 atomicStructs[ret_atomic_loc]->startLocSelection();
106 return ret_atomic_loc;
107}
108
111{
112 assert(atomic_loc >= 0 && atomic_loc < numAtomicLocs);
113 return atomicStructs[atomic_loc]->getLoadLoc();
114}
115
118{
119 assert(atomic_loc >= 0 && atomic_loc < numAtomicLocs);
120 return atomicStructs[atomic_loc]->getStoreLoc();
121}
122
123void
125{
126 assert(atomic_loc >= 0 && atomic_loc < numAtomicLocs);
127 atomicStructs[atomic_loc]->endLocSelection();
128}
129
130void
132{
133 assert(atomic_loc >= 0 && atomic_loc < numAtomicLocs);
134 atomicStructs[atomic_loc]->releaseLoc(loc);
135}
136
137std::string
139{
140 return logTable[loc]->print();
141}
142
143// ------------------- AtomicStruct --------------------------
145 Location loc_begin,
146 Location loc_end)
147{
148 // the location range must have at least 1 location
149 assert(loc_begin <= loc_end);
150
151 atomicLoc = atomic_loc;
152 arraySize = loc_end - loc_begin + 1;
153 locationBase = loc_begin;
154
155 // allocate an array of arrray_size
157
158 // initialize locArray & locProps
159 Location loc;
160 for (int offset = 0; offset < arraySize; ++offset) {
161 loc = locationBase + offset;
162 locArray[offset] = loc;
163 locProps.push_back(LocProperty(offset, 0));
164 }
165
166 // region (1) and (3) are initially empty
167 firstMark = 0;
169 // no request made at this location so far
170 requestCount = 0;
171}
172
174{
175 delete[] locArray;
176}
177
178void
180{
181 assert(firstMark >= 0);
182 assert(firstMark <= secondMark);
183 assert(secondMark <= arraySize);
184 // make sure loadStoreMap has been cleared
185 assert(loadStoreMap.empty());
186
187 // this atomic location is picked for Atomic_ACQ
188 // and Atomic_REL in an episode
189 requestCount += 2;
190 // add two expected values in expectedValues set
191 expectedValues.insert(requestCount - 1);
192 expectedValues.insert(requestCount - 2);
193}
194
197{
198 assert(firstMark >= 0);
199 assert(firstMark <= secondMark);
200 assert(secondMark <= arraySize);
201
202 if (firstMark == arraySize) {
203 // no location can be picked for a LD now, so return an empty location
204 return INVALID_LOCATION;
205 } else {
206 // we can pick any location btw
207 // locArray [firstMark : arraySize-1]
208 int range_size = arraySize - firstMark;
209 Location ret_loc = locArray[
210 firstMark + random_mt.random<unsigned int>() % range_size
211 ];
212
213 // update loadStoreMap
214 LdStMap::iterator it = loadStoreMap.find(ret_loc);
215
216 if (it == loadStoreMap.end()) {
217 // insert a new entry to the map b/c the entry is not there yet
218 // to mark this location has been picked for a LD
219 loadStoreMap.insert(std::pair<Location, LdStBits>
220 (ret_loc, LdStBits(true,false)));
221 } else {
222 // otherwise, just update the LD bit
223 (it->second).first = true;
224 }
225
226 return ret_loc;
227 }
228}
229
232{
233 assert(firstMark >= 0);
234 assert(firstMark <= secondMark);
235 assert(secondMark <= arraySize);
236
237 if (firstMark == secondMark) {
238 // no location can be picked for a ST now, return an invalid location
239 return INVALID_LOCATION;
240 } else {
241 // we can pick any location btw [firstMark : secondMark-1]
242 int range_size = secondMark - firstMark;
243 Location ret_loc = locArray[
244 firstMark + random_mt.random<unsigned int>() % range_size
245 ];
246
247 // update loadStoreMap
248 LdStMap::iterator it = loadStoreMap.find(ret_loc);
249
250 if (it == loadStoreMap.end()) {
251 // insert a new entry to the map b/c the entry is not there yet
252 // to mark this location has been picked for a ST
253 loadStoreMap.insert(std::pair<Location, LdStBits>
254 (ret_loc, LdStBits(false,true)));
255 } else {
256 // otherwise, just update the ST bit
257 (it->second).second = true;
258 }
259
260 return ret_loc;
261 }
262}
263
264// for each entry in loadStoreMap,
265// if <LD_bit, ST_bit> == <1,0>
266// - if the location is in (2), then move it to (3)
267// - if the location is in (3), no move
268// - otherwise, throw an error
269// if <LD_bit, ST_bit> == <0,1> or <1,1>
270// - move it from (2) to (1)
271void
273{
274 assert(firstMark >= 0);
275 assert(firstMark <= secondMark);
276 assert(secondMark <= arraySize);
277
278 for (auto& it : loadStoreMap) {
279 Location loc = it.first;
280 LdStBits p = it.second;
281
282 assert(loc >= locationBase && loc < locationBase + arraySize);
283 LocProperty& loc_prop = locProps[loc - locationBase];
284
285 if (p.first && !p.second) {
286 // this location has been picked for LD(s) but not ST
287 // it must be in either region (2) or (3)
288 assert(inSecondRegion(loc_prop.first) ||
289 inThirdRegion(loc_prop.first));
290
291 if (inSecondRegion(loc_prop.first)) {
292 // there is no owner of this location yet
293 assert(loc_prop.second == 0);
294
295 // pick the last location in (2) to swap
296 Location swapped_loc = locArray[secondMark - 1];
297 LocProperty& swapped_loc_prop =
298 locProps[swapped_loc - locationBase];
299
300 // swap loc and swapped_loc
301 swap(loc_prop, swapped_loc_prop);
302
303 // then, expand (3)
304 secondMark--;
305 }
306
307 // increment the location's number of owners
308 loc_prop.second++;
309 } else if (p.second) {
310 // this location has been picked for ST(s) and/or LD(s)
311 // it must be in region (2)
312 assert(inSecondRegion(loc_prop.first) && loc_prop.second == 0);
313
314 // pick the first location in (2) to swap
315 Location swapped_loc = locArray[firstMark];
316 LocProperty& swapped_loc_prop =
317 locProps[swapped_loc - locationBase];
318
319 // swap loc and swapped_loc
320 swap(loc_prop, swapped_loc_prop);
321
322 // then, expand (1)
323 firstMark++;
324
325 // increment the location's number of owners
326 loc_prop.second++;
327 } else {
328 panic("Location in loadStoreMap but wasn't picked in any"
329 " action\n");
330 }
331 }
332
333 // clear the ld_st_map
334 loadStoreMap.clear();
335}
336
337void
339{
340 assert(loc >= locationBase && loc < locationBase + arraySize);
341
342 LocProperty& loc_prop = locProps[loc - locationBase];
343
344 if (inFirstRegion(loc_prop.first)) {
345 // this location must have exactly 1 owner
346 assert(loc_prop.second == 1);
347
348 // pick the last location in region 1 to swap
349 Location swapped_loc = locArray[firstMark - 1];
350 LocProperty& swapped_loc_prop = locProps[swapped_loc - locationBase];
351
352 // swap loc and swapped_loc
353 swap(loc_prop, swapped_loc_prop);
354
355 // then shrink (1)
356 firstMark--;
357
358 // reset the location's number of owners
359 loc_prop.second = 0;
360 } else if (inThirdRegion(loc_prop.first)) {
361 // this location must have at least 1 owner
362 assert(loc_prop.second >= 1);
363
364 if (loc_prop.second == 1) {
365 // pick the first location in region 3 to swap
366 Location swapped_loc = locArray[secondMark];
367 LocProperty& swapped_loc_prop =
368 locProps[swapped_loc - locationBase];
369
370 // swap loc and swapped_loc
371 swap(loc_prop, swapped_loc_prop);
372
373 // then shrink (3)
374 secondMark++;
375 }
376 // decrement the loc's number of owners
377 loc_prop.second--;
378 } else {
379 // some one else must already reset this counter
380 assert(inSecondRegion(loc_prop.first) && loc_prop.second == 0);
381 }
382}
383
384bool
386{
387 ExpectedValueSet::iterator it = expectedValues.find(val);
388
389 if (it == expectedValues.end()) {
390 std::stringstream exp_val_ss;
391 for (auto& val : expectedValues) {
392 exp_val_ss << " " << val;
393 }
394
395 warn("Expected return values are:\n\t%s\n", exp_val_ss.str());
396
397 return false;
398 }
399
400 // erase this value b/c it's done
401 expectedValues.erase(it);
402
403 return true;
404}
405
406void
408{
409 int new_idx_1 = prop_2.first;
410 int new_idx_2 = prop_1.first;
411
412 // swap the two locations in locArray
413 Location tmp = locArray[prop_1.first];
414 locArray[prop_1.first] = locArray[prop_2.first];
415 locArray[prop_2.first] = tmp;
416
417 // update their new indices
418 prop_1.first = new_idx_1;
419 prop_2.first = new_idx_2;
420}
421
422// ------------------ log table ---------------------
423void
424AddressManager::updateLogTable(Location loc, int thread_id, int episode_id,
425 Value new_value, Tick cur_tick, int cu_id)
426{
427 assert(loc >= 0 && loc < numAtomicLocs + numNormalLocs);
428 logTable[loc]->update(thread_id, cu_id, episode_id, new_value, cur_tick);
429}
430
433{
434 assert(loc >= 0 && loc < numAtomicLocs + numNormalLocs);
435 return logTable[loc]->getLastStoredValue();
436}
437
438bool
440{
441 assert(loc >= 0 && loc < numAtomicLocs);
442 return atomicStructs[loc]->isExpectedValue(ret_val);
443}
444
445} // namespace gem5
AtomicStruct(Location atom_loc, Location loc_begin, Location loc_end)
void swap(LocProperty &prop_1, LocProperty &prop_2)
Addr getAddress(Location loc)
AtomicStructTable atomicStructs
Location getStoreLoc(Location atomic_loc)
Value getLoggedValue(Location loc) const
AddressManager(int n_atomic_locs, int numNormalLocsPerAtomic)
std::string printLastWriter(Location loc) const
void updateLogTable(Location loc, int threadId, int episodeId, Value new_value, Tick curTick, int cuId=-1)
static const int INVALID_LOCATION
Location getLoadLoc(Location atomic_loc)
static const int INVALID_VALUE
void finishLocSelection(Location atomic_loc)
void releaseLocation(Location atomic_loc, Location loc)
bool validateAtomicResp(Location loc, Value ret_val)
STL pair class.
Definition stl.hh:58
static constexpr std::enable_if_t< std::is_integral_v< T >, int > floorLog2(T x)
Definition intmath.hh:59
Random random_mt
Definition random.cc:99
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition random.hh:90
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define warn(...)
Definition logging.hh:256
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 0 > p
Bitfield< 63 > val
Definition misc.hh:804
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
uint64_t Tick
Tick count type.
Definition types.hh:58

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