gem5  v19.0.0.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 
38 
39 #include <cmath>
40 
41 #include "base/intmath.hh"
42 #include "base/logging.hh"
43 #include "params/TreePLRURP.hh"
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  : BaseReplacementPolicy(p), numLeaves(p->num_leaves), count(0),
102  treeInstance(nullptr)
103 {
105  "Number of leaves must be non-zero and a power of 2");
106 }
107 
108 void
110  const std::shared_ptr<ReplacementData>& replacement_data) const
111 {
112  // Cast replacement data
113  std::shared_ptr<TreePLRUReplData> treePLRU_replacement_data =
114  std::static_pointer_cast<TreePLRUReplData>(replacement_data);
115  PLRUTree* tree = treePLRU_replacement_data->tree.get();
116 
117  // Index of the tree entry we are currently checking
118  // Make this entry the new LRU entry
119  uint64_t tree_index = treePLRU_replacement_data->index;
120 
121  // Parse and update tree to make it point to the new LRU
122  do {
123  // Store whether we are coming from a left or right node
124  const bool right = isRightSubtree(tree_index);
125 
126  // Go to the parent tree node
127  tree_index = parentIndex(tree_index);
128 
129  // Update parent node to make it point to the node we just came from
130  tree->at(tree_index) = right;
131  } while (tree_index != 0);
132 }
133 
134 void
135 TreePLRURP::touch(const std::shared_ptr<ReplacementData>& replacement_data)
136 const
137 {
138  // Cast replacement data
139  std::shared_ptr<TreePLRUReplData> treePLRU_replacement_data =
140  std::static_pointer_cast<TreePLRUReplData>(replacement_data);
141  PLRUTree* tree = treePLRU_replacement_data->tree.get();
142 
143  // Index of the tree entry we are currently checking
144  // Make this entry the MRU entry
145  uint64_t tree_index = treePLRU_replacement_data->index;
146 
147  // Parse and update tree to make every bit point away from the new MRU
148  do {
149  // Store whether we are coming from a left or right node
150  const bool right = isRightSubtree(tree_index);
151 
152  // Go to the parent tree node
153  tree_index = parentIndex(tree_index);
154 
155  // Update node to not point to the touched leaf
156  tree->at(tree_index) = !right;
157  } while (tree_index != 0);
158 }
159 
160 void
161 TreePLRURP::reset(const std::shared_ptr<ReplacementData>& replacement_data)
162 const
163 {
164  // A reset has the same functionality of a touch
165  touch(replacement_data);
166 }
167 
170 {
171  // There must be at least one replacement candidate
172  assert(candidates.size() > 0);
173 
174  // Get tree
175  const PLRUTree* tree = std::static_pointer_cast<TreePLRUReplData>(
176  candidates[0]->replacementData)->tree.get();
177 
178  // Index of the tree entry we are currently checking. Start with root.
179  uint64_t tree_index = 0;
180 
181  // Parse tree
182  while (tree_index < tree->size()) {
183  // Go to the next tree entry
184  if (tree->at(tree_index)) {
185  tree_index = rightSubtreeIndex(tree_index);
186  } else {
187  tree_index = leftSubtreeIndex(tree_index);
188  }
189  }
190 
191  // The tree index is currently at the leaf of the victim displaced by the
192  // number of non-leaf nodes
193  return candidates[tree_index - (numLeaves - 1)];
194 }
195 
196 std::shared_ptr<ReplacementData>
198 {
199  // Generate a tree instance every numLeaves created
200  if (count % numLeaves == 0) {
201  treeInstance = new PLRUTree(numLeaves - 1, false);
202  }
203 
204  // Create replacement data using current tree instance
205  TreePLRUReplData* treePLRUReplData = new TreePLRUReplData(
206  (count % numLeaves) + numLeaves - 1,
207  std::shared_ptr<PLRUTree>(treeInstance));
208 
209  // Update instance counter
210  count++;
211 
212  return std::shared_ptr<ReplacementData>(treePLRUReplData);
213 }
214 
215 TreePLRURP*
216 TreePLRURPParams::create()
217 {
218  return new TreePLRURP(this);
219 }
Bitfield< 30, 0 > index
BaseReplacementPolicyParams Params
Convenience typedef.
Definition: base.hh:54
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
uint64_t count
Count of the number of sharers of a replacement data.
TreePLRUReplData(const uint64_t index, std::shared_ptr< PLRUTree > tree)
Default constructor.
Definition: tree_plru_rp.cc:94
void reset(const std::shared_ptr< ReplacementData > &replacement_data) const override
Reset replacement data.
const uint64_t numLeaves
Number of leaves that share a single replacement data.
PLRUTree * treeInstance
Holds the latest temporary tree instance created by instantiateEntry().
A common base class of cache replacement policy objects.
Definition: base.hh:48
void invalidate(const std::shared_ptr< ReplacementData > &replacement_data) const override
Invalidate replacement data to set it as the next probable victim.
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
bool isPowerOf2(const T &n)
Definition: intmath.hh:146
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:203
TreePLRURP(const Params *p)
Construct and initiliaze this replacement policy.
Copyright (c) 2018 Inria All rights reserved.
void touch(const std::shared_ptr< ReplacementData > &replacement_data) const override
Touch an entry to update its replacement data.
Tree-PLRU-specific implementation of replacement data.
std::vector< bool > PLRUTree
Instead of implementing the tree itself with pointers, it is implemented as an array of bits...
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
A replaceable entry is a basic entry in a 2d table-like structure that needs to have replacement func...
ReplaceableEntry * getVictim(const ReplacementCandidates &candidates) const override
Find replacement victim using TreePLRU bits.
Bitfield< 0 > p
std::shared_ptr< ReplacementData > instantiateEntry() override
Instantiate a replacement data entry.
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

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