gem5 v23.0.0.1
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#include <random>
37
38#include "base/intmath.hh"
39#include "base/logging.hh"
40#include "base/random.hh"
41#include "base/trace.hh"
42
43namespace gem5
44{
45
48
49AddressManager::AddressManager(int n_atomic_locs, int n_normal_locs_per_atomic)
50 : numAtomicLocs(n_atomic_locs),
51 numLocsPerAtomic(n_normal_locs_per_atomic)
52{
53 assert(numAtomicLocs > 0 && numLocsPerAtomic > 0);
55
56 // generate random address map
58 for (Location i = 0; i < numAtomicLocs + numNormalLocs; ++i) {
59 // all addresses are sizeof(Value) (i.e., 4-byte) aligned
60 randAddressMap[i] = (Addr)((i + 128) << floorLog2(sizeof(Value)));
61 }
62
63 // randomly shuffle randAddressMap. The seed is determined by the random_mt
64 // gem5 rng. This allows for deterministic randomization.
65 std::shuffle(
66 randAddressMap.begin(),
67 randAddressMap.end(),
68 std::default_random_engine(random_mt.random<unsigned>(0,UINT_MAX))
69 );
70
71 // initialize atomic locations
72 // first and last normal location per atomic location
73 Location first, last;
74 for (Location atomic_loc = 0; atomic_loc < numAtomicLocs; ++atomic_loc) {
75 first = numAtomicLocs + numLocsPerAtomic * atomic_loc;
76 last = first + numLocsPerAtomic - 1;
77 atomicStructs.push_back(new AtomicStruct(atomic_loc, first, last));
78 }
79
80 // initialize log table
81 for (Location loc = 0; loc < numAtomicLocs + numNormalLocs; ++loc) {
82 logTable.push_back(new LastWriter());
83 }
84}
85
87{
88 for (AtomicStruct* atomic_struct : atomicStructs)
89 delete atomic_struct;
90 for (LastWriter* lw : logTable)
91 delete lw;
92}
93
94Addr
96{
97 assert(loc < numAtomicLocs + numNormalLocs && loc >= 0);
98 return randAddressMap[loc];
99}
100
103{
104 Location ret_atomic_loc = random() % 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[firstMark + random() % range_size];
210
211 // update loadStoreMap
212 LdStMap::iterator it = loadStoreMap.find(ret_loc);
213
214 if (it == loadStoreMap.end()) {
215 // insert a new entry to the map b/c the entry is not there yet
216 // to mark this location has been picked for a LD
217 loadStoreMap.insert(std::pair<Location, LdStBits>
218 (ret_loc, LdStBits(true,false)));
219 } else {
220 // otherwise, just update the LD bit
221 (it->second).first = true;
222 }
223
224 return ret_loc;
225 }
226}
227
230{
231 assert(firstMark >= 0);
232 assert(firstMark <= secondMark);
233 assert(secondMark <= arraySize);
234
235 if (firstMark == secondMark) {
236 // no location can be picked for a ST now, return an invalid location
237 return INVALID_LOCATION;
238 } else {
239 // we can pick any location btw [firstMark : secondMark-1]
240 int range_size = secondMark - firstMark;
241 Location ret_loc = locArray[firstMark + random() % range_size];
242
243 // update loadStoreMap
244 LdStMap::iterator it = loadStoreMap.find(ret_loc);
245
246 if (it == loadStoreMap.end()) {
247 // insert a new entry to the map b/c the entry is not there yet
248 // to mark this location has been picked for a ST
249 loadStoreMap.insert(std::pair<Location, LdStBits>
250 (ret_loc, LdStBits(false,true)));
251 } else {
252 // otherwise, just update the ST bit
253 (it->second).second = true;
254 }
255
256 return ret_loc;
257 }
258}
259
260// for each entry in loadStoreMap,
261// if <LD_bit, ST_bit> == <1,0>
262// - if the location is in (2), then move it to (3)
263// - if the location is in (3), no move
264// - otherwise, throw an error
265// if <LD_bit, ST_bit> == <0,1> or <1,1>
266// - move it from (2) to (1)
267void
269{
270 assert(firstMark >= 0);
271 assert(firstMark <= secondMark);
272 assert(secondMark <= arraySize);
273
274 for (auto& it : loadStoreMap) {
275 Location loc = it.first;
276 LdStBits p = it.second;
277
278 assert(loc >= locationBase && loc < locationBase + arraySize);
279 LocProperty& loc_prop = locProps[loc - locationBase];
280
281 if (p.first && !p.second) {
282 // this location has been picked for LD(s) but not ST
283 // it must be in either region (2) or (3)
284 assert(inSecondRegion(loc_prop.first) ||
285 inThirdRegion(loc_prop.first));
286
287 if (inSecondRegion(loc_prop.first)) {
288 // there is no owner of this location yet
289 assert(loc_prop.second == 0);
290
291 // pick the last location in (2) to swap
292 Location swapped_loc = locArray[secondMark - 1];
293 LocProperty& swapped_loc_prop =
294 locProps[swapped_loc - locationBase];
295
296 // swap loc and swapped_loc
297 swap(loc_prop, swapped_loc_prop);
298
299 // then, expand (3)
300 secondMark--;
301 }
302
303 // increment the location's number of owners
304 loc_prop.second++;
305 } else if (p.second) {
306 // this location has been picked for ST(s) and/or LD(s)
307 // it must be in region (2)
308 assert(inSecondRegion(loc_prop.first) && loc_prop.second == 0);
309
310 // pick the first location in (2) to swap
311 Location swapped_loc = locArray[firstMark];
312 LocProperty& swapped_loc_prop =
313 locProps[swapped_loc - locationBase];
314
315 // swap loc and swapped_loc
316 swap(loc_prop, swapped_loc_prop);
317
318 // then, expand (1)
319 firstMark++;
320
321 // increment the location's number of owners
322 loc_prop.second++;
323 } else {
324 panic("Location in loadStoreMap but wasn't picked in any"
325 " action\n");
326 }
327 }
328
329 // clear the ld_st_map
330 loadStoreMap.clear();
331}
332
333void
335{
336 assert(loc >= locationBase && loc < locationBase + arraySize);
337
338 LocProperty& loc_prop = locProps[loc - locationBase];
339
340 if (inFirstRegion(loc_prop.first)) {
341 // this location must have exactly 1 owner
342 assert(loc_prop.second == 1);
343
344 // pick the last location in region 1 to swap
345 Location swapped_loc = locArray[firstMark - 1];
346 LocProperty& swapped_loc_prop = locProps[swapped_loc - locationBase];
347
348 // swap loc and swapped_loc
349 swap(loc_prop, swapped_loc_prop);
350
351 // then shrink (1)
352 firstMark--;
353
354 // reset the location's number of owners
355 loc_prop.second = 0;
356 } else if (inThirdRegion(loc_prop.first)) {
357 // this location must have at least 1 owner
358 assert(loc_prop.second >= 1);
359
360 if (loc_prop.second == 1) {
361 // pick the first location in region 3 to swap
362 Location swapped_loc = locArray[secondMark];
363 LocProperty& swapped_loc_prop =
364 locProps[swapped_loc - locationBase];
365
366 // swap loc and swapped_loc
367 swap(loc_prop, swapped_loc_prop);
368
369 // then shrink (3)
370 secondMark++;
371 }
372 // decrement the loc's number of owners
373 loc_prop.second--;
374 } else {
375 // some one else must already reset this counter
376 assert(inSecondRegion(loc_prop.first) && loc_prop.second == 0);
377 }
378}
379
380bool
382{
383 ExpectedValueSet::iterator it = expectedValues.find(val);
384
385 if (it == expectedValues.end()) {
386 std::stringstream exp_val_ss;
387 for (auto& val : expectedValues) {
388 exp_val_ss << " " << val;
389 }
390
391 warn("Expected return values are:\n\t%s\n", exp_val_ss.str());
392
393 return false;
394 }
395
396 // erase this value b/c it's done
397 expectedValues.erase(it);
398
399 return true;
400}
401
402void
404{
405 int new_idx_1 = prop_2.first;
406 int new_idx_2 = prop_1.first;
407
408 // swap the two locations in locArray
409 Location tmp = locArray[prop_1.first];
410 locArray[prop_1.first] = locArray[prop_2.first];
411 locArray[prop_2.first] = tmp;
412
413 // update their new indices
414 prop_1.first = new_idx_1;
415 prop_2.first = new_idx_2;
416}
417
418// ------------------ log table ---------------------
419void
420AddressManager::updateLogTable(Location loc, int thread_id, int episode_id,
421 Value new_value, Tick cur_tick, int cu_id)
422{
423 assert(loc >= 0 && loc < numAtomicLocs + numNormalLocs);
424 logTable[loc]->update(thread_id, cu_id, episode_id, new_value, cur_tick);
425}
426
429{
430 assert(loc >= 0 && loc < numAtomicLocs + numNormalLocs);
431 return logTable[loc]->getLastStoredValue();
432}
433
434bool
436{
437 assert(loc >= 0 && loc < numAtomicLocs);
438 return atomicStructs[loc]->isExpectedValue(ret_val);
439}
440
441} // 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:776
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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 Mon Jul 10 2023 15:32:02 for gem5 by doxygen 1.9.7