gem5  v22.1.0.0
base.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013,2016,2018-2019 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) 2003-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
46 #include "mem/cache/tags/base.hh"
47 
48 #include <cassert>
49 
50 #include "base/types.hh"
53 #include "mem/request.hh"
54 #include "sim/core.hh"
55 #include "sim/sim_exit.hh"
56 #include "sim/system.hh"
57 
58 namespace gem5
59 {
60 
62  : ClockedObject(p), blkSize(p.block_size), blkMask(blkSize - 1),
63  size(p.size), lookupLatency(p.tag_latency),
64  system(p.system), indexingPolicy(p.indexing_policy),
65  warmupBound((p.warmup_percentage/100.0) * (p.size / p.block_size)),
66  warmedUp(false), numBlocks(p.size / p.block_size),
67  dataBlks(new uint8_t[p.size]), // Allocate data storage in one big chunk
68  stats(*this)
69 {
70  registerExitCallback([this]() { cleanupRefs(); });
71 }
72 
75 {
76  return indexingPolicy->getEntry(set, way);
77 }
78 
79 CacheBlk*
80 BaseTags::findBlock(Addr addr, bool is_secure) const
81 {
82  // Extract block tag
83  Addr tag = extractTag(addr);
84 
85  // Find possible entries that may contain the given address
86  const std::vector<ReplaceableEntry*> entries =
88 
89  // Search for block
90  for (const auto& location : entries) {
91  CacheBlk* blk = static_cast<CacheBlk*>(location);
92  if (blk->matchTag(tag, is_secure)) {
93  return blk;
94  }
95  }
96 
97  // Did not find block
98  return nullptr;
99 }
100 
101 void
103 {
104  assert(!blk->isValid());
105 
106  // Previous block, if existed, has been removed, and now we have
107  // to insert the new one
108 
109  // Deal with what we are bringing in
110  RequestorID requestor_id = pkt->req->requestorId();
111  assert(requestor_id < system->maxRequestors());
112  stats.occupancies[requestor_id]++;
113 
114  // Insert block with tag, src requestor id and task id
115  blk->insert(extractTag(pkt->getAddr()), pkt->isSecure(), requestor_id,
116  pkt->req->taskId());
117 
118  // Check if cache warm up is done
119  if (!warmedUp && stats.tagsInUse.value() >= warmupBound) {
120  warmedUp = true;
122  }
123 
124  // We only need to write into one tag and one data block.
125  stats.tagAccesses += 1;
126  stats.dataAccesses += 1;
127 }
128 
129 void
131 {
132  assert(!dest_blk->isValid());
133  assert(src_blk->isValid());
134 
135  // Move src's contents to dest's
136  *dest_blk = std::move(*src_blk);
137 
138  assert(dest_blk->isValid());
139  assert(!src_blk->isValid());
140 }
141 
142 Addr
144 {
145  return indexingPolicy->extractTag(addr);
146 }
147 
148 void
150 {
151  if (blk.isValid()) {
152  stats.totalRefs += blk.getRefCount();
153  ++stats.sampledRefs;
154  }
155 }
156 
157 void
159 {
160  forEachBlk([this](CacheBlk &blk) { cleanupRefsVisitor(blk); });
161 }
162 
163 void
165 {
166  if (blk.isValid()) {
167  const uint32_t task_id = blk.getTaskId();
168  assert(task_id < context_switch_task_id::NumTaskId);
169  stats.occupanciesTaskId[task_id]++;
170  Tick age = blk.getAge();
171 
172  int age_index;
173  if (age / sim_clock::as_int::us < 10) { // <10us
174  age_index = 0;
175  } else if (age / sim_clock::as_int::us < 100) { // <100us
176  age_index = 1;
177  } else if (age / sim_clock::as_int::ms < 1) { // <1ms
178  age_index = 2;
179  } else if (age / sim_clock::as_int::ms < 10) { // <10ms
180  age_index = 3;
181  } else
182  age_index = 4; // >10ms
183 
184  stats.ageTaskId[task_id][age_index]++;
185  }
186 }
187 
188 void
190 {
191  for (unsigned i = 0; i < context_switch_task_id::NumTaskId; ++i) {
193  for (unsigned j = 0; j < 5; ++j) {
194  stats.ageTaskId[i][j] = 0;
195  }
196  }
197 
198  forEachBlk([this](CacheBlk &blk) { computeStatsVisitor(blk); });
199 }
200 
201 std::string
203 {
204  std::string str;
205 
206  auto print_blk = [&str](CacheBlk &blk) {
207  if (blk.isValid())
208  str += csprintf("\tBlock: %s\n", blk.print());
209  };
210  forEachBlk(print_blk);
211 
212  if (str.empty())
213  str = "no valid tags\n";
214 
215  return str;
216 }
217 
219  : statistics::Group(&_tags),
220  tags(_tags),
221 
222  ADD_STAT(tagsInUse, statistics::units::Rate<
223  statistics::units::Tick, statistics::units::Count>::get(),
224  "Average ticks per tags in use"),
225  ADD_STAT(totalRefs, statistics::units::Count::get(),
226  "Total number of references to valid blocks."),
227  ADD_STAT(sampledRefs, statistics::units::Count::get(),
228  "Sample count of references to valid blocks."),
229  ADD_STAT(avgRefs, statistics::units::Rate<
230  statistics::units::Count, statistics::units::Count>::get(),
231  "Average number of references to valid blocks."),
232  ADD_STAT(warmupTick, statistics::units::Tick::get(),
233  "The tick when the warmup percentage was hit."),
234  ADD_STAT(occupancies, statistics::units::Rate<
235  statistics::units::Count, statistics::units::Tick>::get(),
236  "Average occupied blocks per tick, per requestor"),
237  ADD_STAT(avgOccs, statistics::units::Rate<
238  statistics::units::Ratio, statistics::units::Tick>::get(),
239  "Average percentage of cache occupancy"),
240  ADD_STAT(occupanciesTaskId, statistics::units::Count::get(),
241  "Occupied blocks per task id"),
242  ADD_STAT(ageTaskId, statistics::units::Count::get(),
243  "Occupied blocks per task id, per block age"),
244  ADD_STAT(ratioOccsTaskId, statistics::units::Ratio::get(),
245  "Ratio of occupied blocks and all blocks, per task id"),
246  ADD_STAT(tagAccesses, statistics::units::Count::get(),
247  "Number of tag accesses"),
248  ADD_STAT(dataAccesses, statistics::units::Count::get(),
249  "Number of data accesses")
250 {
251 }
252 
253 void
255 {
256  using namespace statistics;
257 
259 
260  System *system = tags.system;
261 
262  avgRefs = totalRefs / sampledRefs;
263 
264  occupancies
266  .flags(nozero | nonan)
267  ;
268  for (int i = 0; i < system->maxRequestors(); i++) {
269  occupancies.subname(i, system->getRequestorName(i));
270  }
271 
272  avgOccs.flags(nozero | total);
273  for (int i = 0; i < system->maxRequestors(); i++) {
274  avgOccs.subname(i, system->getRequestorName(i));
275  }
276 
277  avgOccs = occupancies / statistics::constant(tags.numBlocks);
278 
279  occupanciesTaskId
281  .flags(nozero | nonan)
282  ;
283 
284  ageTaskId
286  .flags(nozero | nonan)
287  ;
288 
289  ratioOccsTaskId.flags(nozero);
290 
291  ratioOccsTaskId = occupanciesTaskId / statistics::constant(tags.numBlocks);
292 }
293 
294 void
296 {
298 
299  tags.computeStats();
300 }
301 
302 } // namespace gem5
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
virtual std::vector< ReplaceableEntry * > getPossibleEntries(const Addr addr) const =0
Find all possible entries for insertion and replacement of an address.
virtual Addr extractTag(const Addr addr) const
Generate the tag from the given address.
Definition: base.cc:99
ReplaceableEntry * getEntry(const uint32_t set, const uint32_t way) const
Get an entry based on its set and way.
Definition: base.cc:75
A common base class of Cache tagstore objects.
Definition: base.hh:74
virtual void insertBlock(const PacketPtr pkt, CacheBlk *blk)
Insert the new block into the cache and update stats.
Definition: base.cc:102
virtual Addr extractTag(const Addr addr) const
Generate the tag from the given address.
Definition: base.cc:143
BaseTags(const Params &p)
Definition: base.cc:61
const unsigned warmupBound
The number of tags that need to be touched to meet the warmup percentage.
Definition: base.hh:95
virtual CacheBlk * findBlock(Addr addr, bool is_secure) const
Finds the block in the cache without touching it.
Definition: base.cc:80
virtual void forEachBlk(std::function< void(CacheBlk &)> visitor)=0
Visit each block in the tags and apply a visitor.
virtual ReplaceableEntry * findBlockBySetAndWay(int set, int way) const
Find a block given set and way.
Definition: base.cc:74
std::string print()
Print all tags used.
Definition: base.cc:202
System * system
System we are currently operating in.
Definition: base.hh:86
void cleanupRefs()
Average in the reference count for valid blocks when the simulation exits.
Definition: base.cc:158
gem5::BaseTags::BaseTagStats stats
void computeStats()
Computes stats just prior to dump event.
Definition: base.cc:189
bool warmedUp
Marked true when the cache is warmed up.
Definition: base.hh:97
virtual void moveBlock(CacheBlk *src_blk, CacheBlk *dest_blk)
Move a block's metadata to another location decided by the replacement policy.
Definition: base.cc:130
void computeStatsVisitor(CacheBlk &blk)
Update the occupancy and age stats using data from the input block.
Definition: base.cc:164
BaseIndexingPolicy * indexingPolicy
Indexing policy.
Definition: base.hh:89
BaseTagsParams Params
Definition: base.hh:161
void cleanupRefsVisitor(CacheBlk &blk)
Update the reference stats using data from the input block.
Definition: base.cc:149
A Basic Cache block.
Definition: cache_blk.hh:71
Tick getAge() const
Get the block's age, that is, the number of ticks since its insertion.
Definition: cache_blk.hh:302
unsigned getRefCount() const
Get the number of references to this block since insertion.
Definition: cache_blk.hh:291
uint32_t getTaskId() const
Get the task id associated to this block.
Definition: cache_blk.hh:285
void insert(const Addr tag, const bool is_secure, const int src_requestor_ID, const uint32_t task_ID)
Set member variables when a block insertion occurs.
Definition: cache_blk.cc:50
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
bool isSecure() const
Definition: packet.hh:834
Addr getAddr() const
Definition: packet.hh:805
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
A replaceable entry is a basic entry in a 2d table-like structure that needs to have replacement func...
std::string getRequestorName(RequestorID requestor_id)
Get the name of an object for a given request id.
Definition: system.cc:526
RequestorID maxRequestors()
Get the number of requestors registered in the system.
Definition: system.hh:498
virtual bool isValid() const
Checks if the entry is valid.
Definition: tagged_entry.hh:57
virtual bool matchTag(Addr tag, bool is_secure) const
Checks if the given tag information corresponds to this entry's.
Definition: tagged_entry.hh:81
Statistics container.
Definition: group.hh:94
Counter value() const
Return the current value of this stat as its base type.
Definition: statistics.hh:622
STL vector class.
Definition: stl.hh:37
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition: group.hh:75
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: sim_object.cc:76
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:69
virtual void preDumpStats()
Callback before stats are dumped.
Definition: group.cc:99
Declaration of a common base class for cache tagstore objects.
Declaration of a common framework for indexing policies.
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 12, 11 > set
Definition: misc_types.hh:709
Bitfield< 24 > j
Definition: misc_types.hh:57
Bitfield< 54 > p
Definition: pagetable.hh:70
Bitfield< 15 > system
Definition: misc.hh:1004
Bitfield< 3 > addr
Definition: types.hh:84
Tick ms
millisecond
Definition: core.cc:69
Tick us
microsecond
Definition: core.cc:70
const FlagsType nonan
Don't print if this is NAN.
Definition: info.hh:70
const FlagsType nozero
Don't print if this is zero.
Definition: info.hh:68
Temp constant(T val)
Definition: statistics.hh:2865
const FlagsType total
Print the total.
Definition: info.hh:60
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
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
uint16_t RequestorID
Definition: request.hh:95
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
void registerExitCallback(const std::function< void()> &callback)
Register an exit callback.
Definition: core.cc:146
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
statistics::Vector2d ageTaskId
Occupancy of each context/cpu using the cache.
Definition: base.hh:149
statistics::Scalar tagAccesses
Number of tags consulted over all accesses.
Definition: base.hh:155
statistics::Scalar dataAccesses
Number of data blocks consulted over all accesses.
Definition: base.hh:157
statistics::Scalar warmupTick
The tick that the warmup percentage was hit.
Definition: base.hh:137
statistics::AverageVector occupancies
Average occupancy of each requestor using the cache.
Definition: base.hh:140
BaseTagStats(BaseTags &tags)
Definition: base.cc:218
void preDumpStats() override
Callback before stats are dumped.
Definition: base.cc:295
statistics::Vector occupanciesTaskId
Occupancy of each context/cpu using the cache.
Definition: base.hh:146
void regStats() override
Callback to set stat parameters.
Definition: base.cc:254
statistics::Scalar totalRefs
The total number of references to a block before it is replaced.
Definition: base.hh:121
statistics::Average tagsInUse
Per tick average of the number of tags that hold valid data.
Definition: base.hh:118
statistics::Scalar sampledRefs
The number of reference counts sampled.
Definition: base.hh:128

Generated on Wed Dec 21 2022 10:22:30 for gem5 by doxygen 1.9.1