gem5  v21.0.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
tree_plru_rp.cc
Go to the documentation of this file.
1 
36 
37 #include <cmath>
38 
39 #include "base/intmath.hh"
40 #include "base/logging.hh"
41 #include "params/TreePLRURP.hh"
42 
43 namespace ReplacementPolicy {
44 
51 static uint64_t
52 parentIndex(const uint64_t index)
53 {
54  return std::floor((index-1)/2);
55 }
56 
63 static uint64_t
64 leftSubtreeIndex(const uint64_t index)
65 {
66  return 2*index + 1;
67 }
68 
75 static uint64_t
76 rightSubtreeIndex(const uint64_t index)
77 {
78  return 2*index + 2;
79 }
80 
88 static bool
89 isRightSubtree(const uint64_t index)
90 {
91  return index%2 == 0;
92 }
93 
95  const uint64_t index, std::shared_ptr<PLRUTree> tree)
96  : index(index), tree(tree)
97 {
98 }
99 
101  : Base(p), numLeaves(p.num_leaves), count(0), treeInstance(nullptr)
102 {
104  "Number of leaves must be non-zero and a power of 2");
105 }
106 
107 void
109  const std::shared_ptr<ReplacementData>& replacement_data) const
110 {
111  // Cast replacement data
112  std::shared_ptr<TreePLRUReplData> treePLRU_replacement_data =
113  std::static_pointer_cast<TreePLRUReplData>(replacement_data);
114  PLRUTree* tree = treePLRU_replacement_data->tree.get();
115 
116  // Index of the tree entry we are currently checking
117  // Make this entry the new LRU entry
118  uint64_t tree_index = treePLRU_replacement_data->index;
119 
120  // Parse and update tree to make it point to the new LRU
121  do {
122  // Store whether we are coming from a left or right node
123  const bool right = isRightSubtree(tree_index);
124 
125  // Go to the parent tree node
126  tree_index = parentIndex(tree_index);
127 
128  // Update parent node to make it point to the node we just came from
129  tree->at(tree_index) = right;
130  } while (tree_index != 0);
131 }
132 
133 void
134 TreePLRU::touch(const std::shared_ptr<ReplacementData>& replacement_data)
135 const
136 {
137  // Cast replacement data
138  std::shared_ptr<TreePLRUReplData> treePLRU_replacement_data =
139  std::static_pointer_cast<TreePLRUReplData>(replacement_data);
140  PLRUTree* tree = treePLRU_replacement_data->tree.get();
141 
142  // Index of the tree entry we are currently checking
143  // Make this entry the MRU entry
144  uint64_t tree_index = treePLRU_replacement_data->index;
145 
146  // Parse and update tree to make every bit point away from the new MRU
147  do {
148  // Store whether we are coming from a left or right node
149  const bool right = isRightSubtree(tree_index);
150 
151  // Go to the parent tree node
152  tree_index = parentIndex(tree_index);
153 
154  // Update node to not point to the touched leaf
155  tree->at(tree_index) = !right;
156  } while (tree_index != 0);
157 }
158 
159 void
160 TreePLRU::reset(const std::shared_ptr<ReplacementData>& replacement_data)
161 const
162 {
163  // A reset has the same functionality of a touch
164  touch(replacement_data);
165 }
166 
169 {
170  // There must be at least one replacement candidate
171  assert(candidates.size() > 0);
172 
173  // Get tree
174  const PLRUTree* tree = std::static_pointer_cast<TreePLRUReplData>(
175  candidates[0]->replacementData)->tree.get();
176 
177  // Index of the tree entry we are currently checking. Start with root.
178  uint64_t tree_index = 0;
179 
180  // Parse tree
181  while (tree_index < tree->size()) {
182  // Go to the next tree entry
183  if (tree->at(tree_index)) {
184  tree_index = rightSubtreeIndex(tree_index);
185  } else {
186  tree_index = leftSubtreeIndex(tree_index);
187  }
188  }
189 
190  // The tree index is currently at the leaf of the victim displaced by the
191  // number of non-leaf nodes
192  return candidates[tree_index - (numLeaves - 1)];
193 }
194 
195 std::shared_ptr<ReplacementData>
197 {
198  // Generate a tree instance every numLeaves created
199  if (count % numLeaves == 0) {
200  treeInstance = new PLRUTree(numLeaves - 1, false);
201  }
202 
203  // Create replacement data using current tree instance
204  TreePLRUReplData* treePLRUReplData = new TreePLRUReplData(
205  (count % numLeaves) + numLeaves - 1,
206  std::shared_ptr<PLRUTree>(treeInstance));
207 
208  // Update instance counter
209  count++;
210 
211  return std::shared_ptr<ReplacementData>(treePLRUReplData);
212 }
213 
214 } // namespace ReplacementPolicy
ReplacementPolicy::TreePLRU::treeInstance
PLRUTree * treeInstance
Holds the latest temporary tree instance created by instantiateEntry().
Definition: tree_plru_rp.hh:121
ReplaceableEntry
A replaceable entry is a basic entry in a 2d table-like structure that needs to have replacement func...
Definition: replaceable_entry.hh:57
MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:44
ReplacementPolicy::leftSubtreeIndex
static uint64_t leftSubtreeIndex(const uint64_t index)
Get index of the subtree on the left of the given indexed tree.
Definition: tree_plru_rp.cc:64
ReplacementPolicy::rightSubtreeIndex
static uint64_t rightSubtreeIndex(const uint64_t index)
Get index of the subtree on the right of the given indexed tree.
Definition: tree_plru_rp.cc:76
ReplacementPolicy::TreePLRU::touch
void touch(const std::shared_ptr< ReplacementData > &replacement_data) const override
Touch an entry to update its replacement data.
Definition: tree_plru_rp.cc:134
ReplacementPolicy::TreePLRU::TreePLRU
TreePLRU(const Params &p)
Definition: tree_plru_rp.cc:100
ReplacementPolicy::TreePLRU::count
uint64_t count
Count of the number of sharers of a replacement data.
Definition: tree_plru_rp.hh:116
std::vector< bool >
ReplacementPolicy::TreePLRU::TreePLRUReplData::TreePLRUReplData
TreePLRUReplData(const uint64_t index, std::shared_ptr< PLRUTree > tree)
Default constructor.
Definition: tree_plru_rp.cc:94
ReplacementPolicy::TreePLRU::invalidate
void invalidate(const std::shared_ptr< ReplacementData > &replacement_data) const override
Invalidate replacement data to set it as the next probable victim.
Definition: tree_plru_rp.cc:108
ReplacementPolicy
Copyright (c) 2018-2020 Inria All rights reserved.
Definition: stride.hh:64
tree_plru_rp.hh
Copyright (c) 2018-2020 Inria All rights reserved.
ReplacementPolicy::TreePLRU::reset
void reset(const std::shared_ptr< ReplacementData > &replacement_data) const override
Reset replacement data.
Definition: tree_plru_rp.cc:160
ReplacementPolicy::TreePLRU::numLeaves
const uint64_t numLeaves
Number of leaves that share a single replacement data.
Definition: tree_plru_rp.hh:109
ReplacementPolicy::Base::Params
BaseReplacementPolicyParams Params
Definition: base.hh:51
ReplacementPolicy::Base
A common base class of cache replacement policy objects.
Definition: base.hh:48
ReplacementPolicy::isRightSubtree
static bool isRightSubtree(const uint64_t index)
Find out if the subtree at index corresponds to the right or left subtree of its parent tree.
Definition: tree_plru_rp.cc:89
ReplacementPolicy::parentIndex
static uint64_t parentIndex(const uint64_t index)
Get the index of the parent of the given indexed subtree.
Definition: tree_plru_rp.cc:52
ReplacementPolicy::TreePLRU::PLRUTree
std::vector< bool > PLRUTree
Instead of implementing the tree itself with pointers, it is implemented as an array of bits.
Definition: tree_plru_rp.hh:104
logging.hh
ReplacementPolicy::TreePLRU::instantiateEntry
std::shared_ptr< ReplacementData > instantiateEntry() override
Instantiate a replacement data entry.
Definition: tree_plru_rp.cc:196
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
ReplacementPolicy::TreePLRU::TreePLRUReplData
Tree-PLRU-specific implementation of replacement data.
Definition: tree_plru_rp.hh:128
intmath.hh
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
ReplacementPolicy::TreePLRU::getVictim
ReplaceableEntry * getVictim(const ReplacementCandidates &candidates) const override
Find replacement victim using TreePLRU bits.
Definition: tree_plru_rp.cc:168
isPowerOf2
bool isPowerOf2(const T &n)
Definition: intmath.hh:102

Generated on Tue Jun 22 2021 15:28:29 for gem5 by doxygen 1.8.17