gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
compressed_tags.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  * Authors: Daniel Carvalho
29  */
30 
37 
38 #include "base/trace.hh"
39 #include "debug/CacheComp.hh"
43 #include "mem/packet.hh"
44 #include "params/CompressedTags.hh"
45 
47  : SectorTags(p)
48 {
49 }
50 
51 void
53 {
54  // Create blocks and superblocks
57 
58  // Initialize all blocks
59  unsigned blk_index = 0; // index into blks array
60  for (unsigned superblock_index = 0; superblock_index < numSectors;
61  superblock_index++)
62  {
63  // Locate next cache superblock
64  SuperBlk* superblock = &superBlks[superblock_index];
65 
66  // Superblocks must be aware of the block size due to their co-
67  // allocation conditions
68  superblock->setBlkSize(blkSize);
69 
70  // Associate a replacement data entry to the block
72 
73  // Initialize all blocks in this superblock
74  superblock->blks.resize(numBlocksPerSector, nullptr);
75  for (unsigned k = 0; k < numBlocksPerSector; ++k){
76  // Select block within the set to be linked
77  SectorSubBlk*& blk = superblock->blks[k];
78 
79  // Locate next cache block
80  blk = &blks[blk_index];
81 
82  // Associate a data chunk to the block
83  blk->data = &dataBlks[blkSize*blk_index];
84 
85  // Associate superblock to this block
86  blk->setSectorBlock(superblock);
87 
88  // Associate the superblock replacement data to this block
89  blk->replacementData = superblock->replacementData;
90 
91  // Set its index and sector offset
92  blk->setSectorOffset(k);
93 
94  // Update block index
95  ++blk_index;
96  }
97 
98  // Link block to indexing policy
99  indexingPolicy->setEntry(superblock, superblock_index);
100  }
101 }
102 
103 CacheBlk*
104 CompressedTags::findVictim(Addr addr, const bool is_secure,
105  const std::size_t compressed_size,
106  std::vector<CacheBlk*>& evict_blks)
107 {
108  // Get all possible locations of this superblock
109  const std::vector<ReplaceableEntry*> superblock_entries =
111 
112  // Check if the superblock this address belongs to has been allocated. If
113  // so, try co-allocating
114  Addr tag = extractTag(addr);
115  SuperBlk* victim_superblock = nullptr;
116  bool is_co_allocation = false;
117  const uint64_t offset = extractSectorOffset(addr);
118  for (const auto& entry : superblock_entries){
119  SuperBlk* superblock = static_cast<SuperBlk*>(entry);
120  if ((tag == superblock->getTag()) && superblock->isValid() &&
121  (is_secure == superblock->isSecure()) &&
122  !superblock->blks[offset]->isValid() &&
123  superblock->isCompressed() &&
124  superblock->canCoAllocate(compressed_size))
125  {
126  victim_superblock = superblock;
127  is_co_allocation = true;
128  break;
129  }
130  }
131 
132  // If the superblock is not present or cannot be co-allocated a
133  // superblock must be replaced
134  if (victim_superblock == nullptr){
135  // Choose replacement victim from replacement candidates
136  victim_superblock = static_cast<SuperBlk*>(
137  replacementPolicy->getVictim(superblock_entries));
138 
139  // The whole superblock must be evicted to make room for the new one
140  for (const auto& blk : victim_superblock->blks){
141  if (blk->isValid()) {
142  evict_blks.push_back(blk);
143  }
144  }
145  }
146 
147  // Get the location of the victim block within the superblock
148  SectorSubBlk* victim = victim_superblock->blks[offset];
149 
150  // It would be a hit if victim was valid in a co-allocation, and upgrades
151  // do not call findVictim, so it cannot happen
152  if (is_co_allocation){
153  assert(!victim->isValid());
154 
155  // Print all co-allocated blocks
156  DPRINTF(CacheComp, "Co-Allocation: offset %d with blocks\n", offset);
157  for (const auto& blk : victim_superblock->blks){
158  if (blk->isValid()) {
159  DPRINTFR(CacheComp, "\t[%s]\n", blk->print());
160  }
161  }
162  }
163 
164  // Update number of sub-blocks evicted due to a replacement
165  sectorStats.evictionsReplacement[evict_blks.size()]++;
166 
167  return victim;
168 }
169 
170 void
172 {
173  // We check if block can co-allocate before inserting, because this check
174  // assumes the block is still invalid
175  CompressionBlk* compression_blk = static_cast<CompressionBlk*>(blk);
176  const SuperBlk* superblock = static_cast<const SuperBlk*>(
177  compression_blk->getSectorBlock());
178  const bool is_co_allocatable = superblock->isCompressed() &&
179  superblock->canCoAllocate(compression_blk->getSizeBits());
180 
181  // Insert block
182  SectorTags::insertBlock(pkt, blk);
183 
184  // We always store compressed blocks when possible
185  if (is_co_allocatable) {
186  compression_blk->setCompressed();
187  } else {
188  compression_blk->setUncompressed();
189  }
190 }
191 
192 void
193 CompressedTags::forEachBlk(std::function<void(CacheBlk &)> visitor)
194 {
195  for (CompressionBlk& blk : blks) {
196  visitor(blk);
197  }
198 }
199 
200 bool
201 CompressedTags::anyBlk(std::function<bool(CacheBlk &)> visitor)
202 {
203  for (CompressionBlk& blk : blks) {
204  if (visitor(blk)) {
205  return true;
206  }
207  }
208  return false;
209 }
210 
212 CompressedTagsParams::create()
213 {
214  return new CompressedTags(this);
215 }
#define DPRINTF(x,...)
Definition: trace.hh:229
void forEachBlk(std::function< void(CacheBlk &)> visitor) override
Visit each sub-block in the tags and apply a visitor.
const SectorBlk * getSectorBlock() const
Get sector block associated to this block.
Definition: sector_blk.cc:51
A SectorTags cache tag store.
Definition: sector_tags.hh:60
int extractSectorOffset(Addr addr) const
Calculate a block&#39;s offset in a sector from the address.
Definition: sector_tags.cc:277
bool isValid() const
Checks that a block is valid.
Definition: cache_blk.hh:206
void insertBlock(const PacketPtr pkt, CacheBlk *blk) override
Insert the new block into the cache and update replacement data.
virtual std::vector< ReplaceableEntry * > getPossibleEntries(const Addr addr) const =0
Find all possible entries for insertion and replacement of an address.
Declaration of a compressed set associative tag store using superblocks.
CompressedTags(const Params *p)
Construct and initialize this tag store.
CacheBlk * findVictim(Addr addr, const bool is_secure, const std::size_t compressed_size, std::vector< CacheBlk *> &evict_blks) override
Find replacement victim based on address.
ip6_addr_t addr
Definition: inet.hh:335
std::vector< SectorSubBlk * > blks
List of blocks associated to this sector.
Definition: sector_blk.hh:169
virtual Addr extractTag(const Addr addr) const
Generate the tag from the given address.
Definition: base.cc:131
A sector is composed of sub-blocks, and each sub-block has information regarding its sector and a poi...
Definition: sector_blk.hh:50
void setUncompressed()
Clear compression bit.
Definition: super_blk.cc:59
std::unique_ptr< uint8_t[]> dataBlks
The data blocks, 1 per cache block.
Definition: base.hh:103
Bitfield< 23, 0 > offset
Definition: types.hh:154
virtual ReplaceableEntry * getVictim(const ReplacementCandidates &candidates) const =0
Find replacement victim among candidates.
bool isValid() const
Checks that a sector block is valid.
Definition: sector_blk.cc:124
void insertBlock(const PacketPtr pkt, CacheBlk *blk) override
Insert the new block into the cache and update replacement data.
Definition: sector_tags.cc:174
std::size_t getSizeBits() const
Definition: super_blk.cc:65
BaseTagsParams Params
Definition: base.hh:161
A Basic Cache block.
Definition: cache_blk.hh:87
Addr getTag() const
Get tag associated to this block.
Definition: sector_blk.cc:150
bool canCoAllocate(const std::size_t compressed_size) const
Checks whether a superblock can co-allocate given compressed data block.
Definition: super_blk.cc:110
std::shared_ptr< ReplacementData > replacementData
Replacement data associated to this entry.
A CompressedTags cache tag store.
Bitfield< 23 > k
Definition: dt_constants.hh:80
Stats::Vector evictionsReplacement
Number of sub-blocks evicted due to a replacement.
Definition: sector_tags.hh:101
A superblock is composed of sub-blocks, and each sub-block has information regarding its superblock a...
Definition: super_blk.hh:50
void setSectorBlock(SectorBlk *sector_blk)
Set sector block associated to this block.
Definition: sector_blk.cc:44
const unsigned blkSize
The block size of the cache.
Definition: base.hh:77
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
virtual std::shared_ptr< ReplacementData > instantiateEntry()=0
Instantiate a replacement data entry.
const unsigned numSectors
The number of sectors in the cache.
Definition: sector_tags.hh:82
void setSectorOffset(const int sector_offset)
Set offset of this sub-block within the sector.
Definition: sector_blk.cc:57
void setCompressed()
Set compression bit.
Definition: super_blk.cc:53
void setEntry(ReplaceableEntry *entry, const uint64_t index)
Associate a pointer to an entry to its physical counterpart.
Definition: base.cc:81
BaseReplacementPolicy * replacementPolicy
Replacement policy.
Definition: sector_tags.hh:76
bool anyBlk(std::function< bool(CacheBlk &)> visitor) override
Find if any of the sub-blocks satisfies a condition.
Declaration of the Packet class.
bool isCompressed(const CompressionBlk *ignored_blk=nullptr) const
Returns whether the superblock contains compressed blocks or not.
Definition: super_blk.cc:97
bool isSecure() const
Checks that a sector block is secure.
Definition: sector_blk.cc:137
BaseIndexingPolicy * indexingPolicy
Indexing policy.
Definition: base.hh:89
const unsigned numBlocks
the number of blocks in the cache
Definition: base.hh:100
const unsigned numBlocksPerSector
Number of data blocks per sector.
Definition: sector_tags.hh:79
SectorTags::SectorTagsStats sectorStats
Bitfield< 0 > p
void setBlkSize(const std::size_t blk_size)
Set block size.
Definition: super_blk.cc:119
std::vector< CompressionBlk > blks
The cache blocks.
Declaration of a common framework for indexing policies.
void tagsInit() override
Initialize blocks as SuperBlk and CompressionBlk instances.
A basic compression superblock.
Definition: super_blk.hh:127
uint8_t * data
Contains a copy of the data in this block for easy access.
Definition: cache_blk.hh:102
std::vector< SuperBlk > superBlks
The cache superblocks.
#define DPRINTFR(...)
Definition: trace.hh:231

Generated on Fri Feb 28 2020 16:27:02 for gem5 by doxygen 1.8.13