gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
fa_lru.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013,2016 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  * Authors: Erik Hallnor
41  */
42 
48 #include "mem/cache/tags/fa_lru.hh"
49 
50 #include <cassert>
51 #include <sstream>
52 
53 #include "base/intmath.hh"
54 #include "base/misc.hh"
55 
56 using namespace std;
57 
59  : BaseTags(p), cacheBoundaries(nullptr)
60 {
61  if (!isPowerOf2(blkSize))
62  fatal("cache block size (in bytes) `%d' must be a power of two",
63  blkSize);
64  if (!isPowerOf2(size))
65  fatal("Cache Size must be power of 2 for now");
66 
67  // Track all cache sizes from 128K up by powers of 2
68  numCaches = floorLog2(size) - 17;
69  if (numCaches >0){
71  cacheMask = (ULL(1) << numCaches) - 1;
72  } else {
73  cacheMask = 0;
74  }
75 
78 
79  blks = new FALRUBlk[numBlocks];
80  head = &(blks[0]);
81  tail = &(blks[numBlocks-1]);
82 
83  head->prev = nullptr;
84  head->next = &(blks[1]);
86 
87  tail->prev = &(blks[numBlocks-2]);
88  tail->next = nullptr;
89  tail->inCache = 0;
90 
91  unsigned index = (1 << 17) / blkSize;
92  unsigned j = 0;
93  int flags = cacheMask;
94  for (unsigned i = 1; i < numBlocks - 1; i++) {
95  blks[i].inCache = flags;
96  if (i == index - 1){
97  cacheBoundaries[j] = &(blks[i]);
98  flags &= ~ (1<<j);
99  ++j;
100  index = index << 1;
101  }
102  blks[i].prev = &(blks[i-1]);
103  blks[i].next = &(blks[i+1]);
104  blks[i].isTouched = false;
105  blks[i].set = 0;
106  blks[i].way = i;
107  }
108  assert(j == numCaches);
109  assert(index == numBlocks);
110  //assert(check());
111 }
112 
114 {
115  if (numCaches)
116  delete[] cacheBoundaries;
117 
118  delete[] blks;
119 }
120 
121 void
123 {
124  using namespace Stats;
126  hits
127  .init(numCaches+1)
128  .name(name() + ".falru_hits")
129  .desc("The number of hits in each cache size.")
130  ;
131  misses
132  .init(numCaches+1)
133  .name(name() + ".falru_misses")
134  .desc("The number of misses in each cache size.")
135  ;
136  accesses
137  .name(name() + ".falru_accesses")
138  .desc("The number of accesses to the FA LRU cache.")
139  ;
140 
141  for (unsigned i = 0; i <= numCaches; ++i) {
142  stringstream size_str;
143  if (i < 3){
144  size_str << (1<<(i+7)) <<"K";
145  } else {
146  size_str << (1<<(i-3)) <<"M";
147  }
148 
149  hits.subname(i, size_str.str());
150  hits.subdesc(i, "Hits in a " + size_str.str() +" cache");
151  misses.subname(i, size_str.str());
152  misses.subdesc(i, "Misses in a " + size_str.str() +" cache");
153  }
154 }
155 
156 FALRUBlk *
158 {
159  tagIterator iter = tagHash.find(addr);
160  if (iter != tagHash.end()) {
161  return (*iter).second;
162  }
163  return nullptr;
164 }
165 
166 void
168 {
169  assert(blk);
170  tagsInUse--;
171 }
172 
173 CacheBlk*
174 FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat)
175 {
176  return accessBlock(addr, is_secure, lat, 0);
177 }
178 
179 CacheBlk*
180 FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat, int *inCache)
181 {
182  accesses++;
183  int tmp_in_cache = 0;
184  Addr blkAddr = blkAlign(addr);
185  FALRUBlk* blk = hashLookup(blkAddr);
186 
187  if (blk && blk->isValid()) {
188  // If a cache hit
189  lat = accessLatency;
190  // Check if the block to be accessed is available. If not,
191  // apply the accessLatency on top of block->whenReady.
192  if (blk->whenReady > curTick() &&
193  cache->ticksToCycles(blk->whenReady - curTick()) >
194  accessLatency) {
195  lat = cache->ticksToCycles(blk->whenReady - curTick()) +
197  }
198  assert(blk->tag == blkAddr);
199  tmp_in_cache = blk->inCache;
200  for (unsigned i = 0; i < numCaches; i++) {
201  if (1<<i & blk->inCache) {
202  hits[i]++;
203  } else {
204  misses[i]++;
205  }
206  }
207  hits[numCaches]++;
208  if (blk != head){
209  moveToHead(blk);
210  }
211  } else {
212  // If a cache miss
213  lat = lookupLatency;
214  blk = nullptr;
215  for (unsigned i = 0; i <= numCaches; ++i) {
216  misses[i]++;
217  }
218  }
219  if (inCache) {
220  *inCache = tmp_in_cache;
221  }
222 
223  //assert(check());
224  return blk;
225 }
226 
227 
228 CacheBlk*
229 FALRU::findBlock(Addr addr, bool is_secure) const
230 {
231  Addr blkAddr = blkAlign(addr);
232  FALRUBlk* blk = hashLookup(blkAddr);
233 
234  if (blk && blk->isValid()) {
235  assert(blk->tag == blkAddr);
236  } else {
237  blk = nullptr;
238  }
239  return blk;
240 }
241 
242 CacheBlk*
243 FALRU::findBlockBySetAndWay(int set, int way) const
244 {
245  assert(set == 0);
246  return &blks[way];
247 }
248 
249 CacheBlk*
251 {
252  FALRUBlk * blk = tail;
253  assert(blk->inCache == 0);
254  moveToHead(blk);
255  tagHash.erase(blk->tag);
256  tagHash[blkAlign(addr)] = blk;
257  if (blk->isValid()) {
258  replacements[0]++;
259  } else {
260  tagsInUse++;
261  blk->isTouched = true;
262  if (!warmedUp && tagsInUse.value() >= warmupBound) {
263  warmedUp = true;
264  warmupCycle = curTick();
265  }
266  }
267  //assert(check());
268  return blk;
269 }
270 
271 void
273 {
274 }
275 
276 void
278 {
279  int updateMask = blk->inCache ^ cacheMask;
280  for (unsigned i = 0; i < numCaches; i++){
281  if ((1<<i) & updateMask) {
282  cacheBoundaries[i]->inCache &= ~(1<<i);
284  } else if (cacheBoundaries[i] == blk) {
285  cacheBoundaries[i] = blk->prev;
286  }
287  }
288  blk->inCache = cacheMask;
289  if (blk != head) {
290  if (blk == tail){
291  assert(blk->next == nullptr);
292  tail = blk->prev;
293  tail->next = nullptr;
294  } else {
295  blk->prev->next = blk->next;
296  blk->next->prev = blk->prev;
297  }
298  blk->next = head;
299  blk->prev = nullptr;
300  head->prev = blk;
301  head = blk;
302  }
303 }
304 
305 bool
307 {
308  FALRUBlk* blk = head;
309  int tot_size = 0;
310  int boundary = 1<<17;
311  int j = 0;
312  int flags = cacheMask;
313  while (blk) {
314  tot_size += blkSize;
315  if (blk->inCache != flags) {
316  return false;
317  }
318  if (tot_size == boundary && blk != tail) {
319  if (cacheBoundaries[j] != blk) {
320  return false;
321  }
322  flags &=~(1 << j);
323  boundary = boundary<<1;
324  ++j;
325  }
326  blk = blk->next;
327  }
328  return true;
329 }
330 
331 FALRU *
332 FALRUParams::create()
333 {
334  return new FALRU(this);
335 }
336 
Counter value() const
Return the current value of this stat as its base type.
Definition: statistics.hh:677
Bitfield< 30, 0 > index
const Cycles lookupLatency
The tag lookup latency of the cache.
Definition: base.hh:75
FALRU(const Params *p)
Construct and initialize this cache tagstore.
Definition: fa_lru.cc:58
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation...
Definition: statistics.hh:358
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:83
bool warmedUp
Marked true when the cache is warmed up.
Definition: base.hh:91
Tick whenReady
Which curTick() will this block be accessable.
Definition: blk.hh:103
Bitfield< 7 > i
Definition: miscregs.hh:1378
CacheBlk * findVictim(Addr addr) override
Find a replacement block for the address provided.
Definition: fa_lru.cc:250
Addr tag
Data block tag value.
Definition: blk.hh:86
Cycles ticksToCycles(Tick t) const
Stats::Average tagsInUse
Per cycle average of the number of tags that hold valid data.
Definition: base.hh:105
ip6_addr_t addr
Definition: inet.hh:335
FALRUBlk * head
The MRU block.
Definition: fa_lru.hh:106
A fully associative LRU cache.
Definition: fa_lru.hh:88
void regStats()
Register local statistics.
Definition: base.cc:77
CacheBlk * findBlock(Addr addr, bool is_secure) const override
Find the block in the cache, do not update the replacement data.
Definition: fa_lru.cc:229
Derived & subdesc(off_type index, const std::string &desc)
Set the subfield description for the given index and marks this stat to print at the end of simulatio...
Definition: statistics.hh:382
FALRUBlk * next
The next block in LRU order.
Definition: fa_lru.hh:69
Stats::Vector replacements
Number of replacements of valid blocks per thread.
Definition: base.hh:103
void insertBlock(PacketPtr pkt, CacheBlk *blk) override
Definition: fa_lru.cc:272
int cacheMask
A mask for the FALRUBlk::inCache bits.
Definition: fa_lru.hh:98
Derived & init(size_type size)
Set this vector to have the given size.
Definition: statistics.hh:1118
Declaration of a fully associative LRU tag store.
FALRUBlk ** cacheBoundaries
Array of pointers to blocks at the cache size boundaries.
Definition: fa_lru.hh:96
FALRUBlk * tail
The LRU block.
Definition: fa_lru.hh:108
int way
Definition: blk.hh:109
Addr blkAlign(Addr addr) const
Align an address to the block size.
Definition: base.hh:196
BaseTagsParams Params
Definition: base.hh:151
Tick curTick()
The current simulated tick.
Definition: core.hh:47
A Basic Cache block.
Definition: blk.hh:79
unsigned numBlocks
the number of blocks in the cache
Definition: base.hh:94
A fully associative cache block.
Definition: fa_lru.hh:63
Stats::Vector hits
Hits in each cache size >= 128K.
Definition: fa_lru.hh:146
void invalidate(CacheBlk *blk) override
Invalidate a cache block.
Definition: fa_lru.cc:167
#define fatal(...)
Definition: misc.hh:163
unsigned numCaches
The number of different size caches being tracked.
Definition: fa_lru.hh:100
bool isPowerOf2(const T &n)
Definition: intmath.hh:73
const Cycles accessLatency
The total access latency of the cache.
Definition: base.hh:81
Stats::Scalar warmupCycle
The cycle that the warmup percentage was hit.
Definition: base.hh:124
hash_t tagHash
The address hash table.
Definition: fa_lru.hh:116
void moveToHead(FALRUBlk *blk)
Move a cache block to the MRU position.
Definition: fa_lru.cc:277
const unsigned blkSize
The block size of the cache.
Definition: base.hh:69
Stats::Scalar accesses
Total number of accesses.
Definition: fa_lru.hh:150
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
#define ULL(N)
uint64_t constant
Definition: types.hh:50
~FALRU()
Definition: fa_lru.cc:113
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:245
Bitfield< 24 > j
Definition: miscregs.hh:1369
Stats::Vector misses
Misses in each cache size >= 128K.
Definition: fa_lru.hh:148
int inCache
A bit mask of the sizes of cache that this block is resident in.
Definition: fa_lru.hh:81
Derived & name(const std::string &name)
Set the name and marks this stat to print at the end of simulation.
Definition: statistics.hh:254
int floorLog2(unsigned x)
Definition: intmath.hh:100
BaseCache * cache
Pointer to the parent cache.
Definition: base.hh:83
void regStats() override
Register the stats for this object.
Definition: fa_lru.cc:122
virtual const std::string name() const
Definition: sim_object.hh:117
bool isTouched
Has this block been touched?
Definition: fa_lru.hh:71
CacheBlk * accessBlock(Addr addr, bool is_secure, Cycles &lat, int *inCache)
Access block and update replacement data.
Definition: fa_lru.cc:180
FALRUBlk * blks
The cache blocks.
Definition: fa_lru.hh:103
FALRUBlk * prev
The previous block in LRU order.
Definition: fa_lru.hh:67
Derived & desc(const std::string &_desc)
Set the description and marks this stat to print at the end of simulation.
Definition: statistics.hh:287
int set
The set and way this block belongs to.
Definition: blk.hh:109
FALRUBlk * hashLookup(Addr addr) const
Find the cache block for the given address.
Definition: fa_lru.cc:157
int warmupBound
The number of tags that need to be touched to meet the warmup percentage.
Definition: base.hh:89
hash_t::const_iterator tagIterator
Iterator into the address hash table.
Definition: fa_lru.hh:113
bool isValid() const
Checks that a block is valid.
Definition: blk.hh:203
Bitfield< 0 > p
A common base class of Cache tagstore objects.
Definition: base.hh:65
bool check()
Check to make sure all the cache boundaries are still where they should be.
Definition: fa_lru.cc:306
CacheBlk * findBlockBySetAndWay(int set, int way) const override
Find the cache block given set and way.
Definition: fa_lru.cc:243
const unsigned size
The size of the cache.
Definition: base.hh:73

Generated on Fri Jun 9 2017 13:03:48 for gem5 by doxygen 1.8.6