stack_dist_calc.hh (10614:da37aec3ed1a) stack_dist_calc.hh (10995:a114e2712642)
1/*
1/*
2 * Copyright (c) 2014 ARM Limited
2 * Copyright (c) 2014-2015 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 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Kanishk Sugand
38 * Andreas Hansson
39 */
40
41#ifndef __MEM_STACK_DIST_CALC_HH__
42#define __MEM_STACK_DIST_CALC_HH__
43
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 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Kanishk Sugand
38 * Andreas Hansson
39 */
40
41#ifndef __MEM_STACK_DIST_CALC_HH__
42#define __MEM_STACK_DIST_CALC_HH__
43
44#include <limits>
44#include <map>
45#include <vector>
46
47#include "base/types.hh"
45#include <map>
46#include <vector>
47
48#include "base/types.hh"
48#include "mem/packet.hh"
49#include "params/StackDistCalc.hh"
50#include "sim/sim_object.hh"
51#include "sim/stats.hh"
52
53/**
54 * The stack distance calculator is a passive object that merely
55 * observes the addresses pass to it. It calculates stack distances
56 * of incoming addresses based on the partial sum hierarchy tree
57 * algorithm described by Alamasi et al.
58 * http://doi.acm.org/10.1145/773039.773043.
59 *
60 * A tree structure is maintained and updated at each transaction
61 * (unique or non-unique). The tree is implemented as an STL vector
62 * with layers of the form <map> Each layer in this tree is an
63 * ordered map <uint64_t, Node*>. Nodes are structs which take form
64 * of leaf, intermediate and root nodes. For example, in a tree with 3
65 * layers, tree[0][5] gives a leaf node pointer for key=5 tree[1][1]
66 * gives an intermediate node pointer for key=1 tree[2][0] gives the
67 * root node in the tree.
68 *
69 * At every transaction a hash-map (aiMap) is looked up to check if
70 * the address was already encountered before. Based on this lookup a
71 * transaction can be termed as unique or non-unique.
72 *
73 * In addition to the normal stack distance calculation, a feature to
74 * mark an old node in the tree is added. This is useful if it is
75 * required to see the reuse pattern. For example, BackInvalidates
76 * from a lower level (e.g. membus to L2), can be marked (isMarked
77 * flag of Node set to True). Then later if this same address is
78 * accessed (by L1), the value of the isMarked flag would be
79 * True. This would give some insight on how the BackInvalidates
80 * policy of the lower level affect the read/write accesses in an
81 * application.
82 *
83 * There are two functions provided to interface with the calculator:
84 * 1. pair<uint64_t, bool> calcStackDistAndUpdate(Addr r_address,
85 * bool addNewNode)
86 * At every unique transaction a new leaf node is added at tree[0](leaf layer)
87 * and linked to the layer above (if addNewNode is True). The sums of all
88 * the intermediate nodes is updated till the root. The stack-distance is
89 * returned as a Constant representing INFINITY.
90 *
91 * At every non-unique transaction the tree is traversed from the
92 * leaf at the returned index to the root, the old node is deleted
93 * from the tree, and the sums (to the right are collected) and
94 * decremented. The collected sum represets the stack distance of the
95 * found node. If this node was marked then a bool flag set to True
96 * is returned with the stack_distance. During this operation a node
97 * is discarded at the leaf layer always. Moreover during the
98 * traversal upwards using the updateSum() method, if an intermediate
99 * node is found with no children connected to it, then that is
100 * discarded too.
101 *
102 * The return value of this function is a pair representing the
103 * stack_distance and the value of the marked flag.
104 *
105 * 2. pair<uint64_t , bool> calcStackDist(Addr r_address, bool mark)
106 * This is a stripped down version of the above function which is used to
107 * just inspect the tree, and mark a leaf node (if mark flag is set). The
108 * functionality to add a new node is removed.
109 *
110 * At every unique transaction the stack-distance is returned as a constant
111 * representing INFINITY.
112 *
113 * At every non-unique transaction the tree is traversed from the
114 * leaf at the returned index to the root, and the sums (to the right)
115 * are collected. The collected sum represets the stack distance of
116 * the found node.
117 *
118 * This function does NOT Modify the stack. (No node is added or
119 * deleted). It is just used to mark a node already created and get
120 * its stack distance.
121 *
122 * The return value of this function is a pair representing the stack
123 * distance and the value of the marked flag.
124 *
125 * The table below depicts the usage of the Algorithm using the functions:
126 * pair<uint64_t Stack_dist, bool isMarked> calcStackDistAndUpdate
127 * (Addr r_address, bool addNewNode)
128 * pair<uint64_t Stack_dist, bool isMarked> calcStackDist
129 * (Addr r_address, bool mark)
130 *
131 * | Function | Arguments |Return Val |Use For|
132 * |calcStackDistAndUpdate|r_address, True|I/SD,False |A,GD,GM|
133 * |calcStackDistAndUpdate|r_address,False|SD,prevMark|D,GD,GM|
134 * |calcStackDist |r_address,False|SD,prevMark| GD,GM|
135 * |calcStackDist |r_address, True|SD,prevMark| GD,GM|
136 *
137 * (*A: Allocate an address in stack, if old entry present then it is deleted,
138 * *U: Delete old-address from stack, no new entry is added
139 * *GD: Get-Stack distance of an address,
140 * *GM: Get value of Mark flag, indicates if that address has been touched
141 * before,
142 * *I: stack-distance = infinity,
143 * *SD: Stack Distance
144 * *r_address: address to be added, *prevMark: value of isMarked flag
145 * of the Node)
146 *
147 * Invalidates refer to a type of packet that removes something from
148 * a cache, either autonoumously (due-to cache's own replacement
149 * policy), or snoops from other caches which invalidate something
150 * inside our cache.
151 *
152 * Usage | Function to use |Typical Use |
153 * Add new entry |calcStackDistAndUpdate|Read/Write Allocate |
154 * Delete Old Entry |calcStackDistAndUpdate|Writebacks/Cleanevicts|
155 * Dist.of Old entry|calcStackDist |Cleanevicts/Invalidate|
156 *
157 * Node Balancing: The tree structure is maintained by an
158 * updateTree() operation called when an intermediate node is
159 * required. The update operation is roughly categorized as a root
160 * update or intermediate layer update. When number of leaf nodes
161 * grow over a power of 2 then a new layer is added at the top of the
162 * tree and a new root node is initialized. The old node at the lower
163 * layer is connected to this. In an intermediate node update
164 * operation a new intermediate node is added to the required layer.
165 *
166 * Debugging: Debugging can be enabled by setting the verifyStack flag
167 * true. Debugging is implemented using a dummy stack that behaves in
168 * a naive way, using STL vectors (i.e each unique address is pushed
169 * on the top of an STL vector stack, and SD is returned as
170 * Infinity. If a non unique address is encountered then the previous
171 * entry in the STL vector is removed, all the entities above it are
172 * pushed down, and the address is pushed at the top of the stack).
173 *
174 * A printStack(int numOfEntitiesToPrint) is provided to print top n entities
175 * in both (tree and STL based dummy stack).
176 */
49
50/**
51 * The stack distance calculator is a passive object that merely
52 * observes the addresses pass to it. It calculates stack distances
53 * of incoming addresses based on the partial sum hierarchy tree
54 * algorithm described by Alamasi et al.
55 * http://doi.acm.org/10.1145/773039.773043.
56 *
57 * A tree structure is maintained and updated at each transaction
58 * (unique or non-unique). The tree is implemented as an STL vector
59 * with layers of the form <map> Each layer in this tree is an
60 * ordered map <uint64_t, Node*>. Nodes are structs which take form
61 * of leaf, intermediate and root nodes. For example, in a tree with 3
62 * layers, tree[0][5] gives a leaf node pointer for key=5 tree[1][1]
63 * gives an intermediate node pointer for key=1 tree[2][0] gives the
64 * root node in the tree.
65 *
66 * At every transaction a hash-map (aiMap) is looked up to check if
67 * the address was already encountered before. Based on this lookup a
68 * transaction can be termed as unique or non-unique.
69 *
70 * In addition to the normal stack distance calculation, a feature to
71 * mark an old node in the tree is added. This is useful if it is
72 * required to see the reuse pattern. For example, BackInvalidates
73 * from a lower level (e.g. membus to L2), can be marked (isMarked
74 * flag of Node set to True). Then later if this same address is
75 * accessed (by L1), the value of the isMarked flag would be
76 * True. This would give some insight on how the BackInvalidates
77 * policy of the lower level affect the read/write accesses in an
78 * application.
79 *
80 * There are two functions provided to interface with the calculator:
81 * 1. pair<uint64_t, bool> calcStackDistAndUpdate(Addr r_address,
82 * bool addNewNode)
83 * At every unique transaction a new leaf node is added at tree[0](leaf layer)
84 * and linked to the layer above (if addNewNode is True). The sums of all
85 * the intermediate nodes is updated till the root. The stack-distance is
86 * returned as a Constant representing INFINITY.
87 *
88 * At every non-unique transaction the tree is traversed from the
89 * leaf at the returned index to the root, the old node is deleted
90 * from the tree, and the sums (to the right are collected) and
91 * decremented. The collected sum represets the stack distance of the
92 * found node. If this node was marked then a bool flag set to True
93 * is returned with the stack_distance. During this operation a node
94 * is discarded at the leaf layer always. Moreover during the
95 * traversal upwards using the updateSum() method, if an intermediate
96 * node is found with no children connected to it, then that is
97 * discarded too.
98 *
99 * The return value of this function is a pair representing the
100 * stack_distance and the value of the marked flag.
101 *
102 * 2. pair<uint64_t , bool> calcStackDist(Addr r_address, bool mark)
103 * This is a stripped down version of the above function which is used to
104 * just inspect the tree, and mark a leaf node (if mark flag is set). The
105 * functionality to add a new node is removed.
106 *
107 * At every unique transaction the stack-distance is returned as a constant
108 * representing INFINITY.
109 *
110 * At every non-unique transaction the tree is traversed from the
111 * leaf at the returned index to the root, and the sums (to the right)
112 * are collected. The collected sum represets the stack distance of
113 * the found node.
114 *
115 * This function does NOT Modify the stack. (No node is added or
116 * deleted). It is just used to mark a node already created and get
117 * its stack distance.
118 *
119 * The return value of this function is a pair representing the stack
120 * distance and the value of the marked flag.
121 *
122 * The table below depicts the usage of the Algorithm using the functions:
123 * pair<uint64_t Stack_dist, bool isMarked> calcStackDistAndUpdate
124 * (Addr r_address, bool addNewNode)
125 * pair<uint64_t Stack_dist, bool isMarked> calcStackDist
126 * (Addr r_address, bool mark)
127 *
128 * | Function | Arguments |Return Val |Use For|
129 * |calcStackDistAndUpdate|r_address, True|I/SD,False |A,GD,GM|
130 * |calcStackDistAndUpdate|r_address,False|SD,prevMark|D,GD,GM|
131 * |calcStackDist |r_address,False|SD,prevMark| GD,GM|
132 * |calcStackDist |r_address, True|SD,prevMark| GD,GM|
133 *
134 * (*A: Allocate an address in stack, if old entry present then it is deleted,
135 * *U: Delete old-address from stack, no new entry is added
136 * *GD: Get-Stack distance of an address,
137 * *GM: Get value of Mark flag, indicates if that address has been touched
138 * before,
139 * *I: stack-distance = infinity,
140 * *SD: Stack Distance
141 * *r_address: address to be added, *prevMark: value of isMarked flag
142 * of the Node)
143 *
144 * Invalidates refer to a type of packet that removes something from
145 * a cache, either autonoumously (due-to cache's own replacement
146 * policy), or snoops from other caches which invalidate something
147 * inside our cache.
148 *
149 * Usage | Function to use |Typical Use |
150 * Add new entry |calcStackDistAndUpdate|Read/Write Allocate |
151 * Delete Old Entry |calcStackDistAndUpdate|Writebacks/Cleanevicts|
152 * Dist.of Old entry|calcStackDist |Cleanevicts/Invalidate|
153 *
154 * Node Balancing: The tree structure is maintained by an
155 * updateTree() operation called when an intermediate node is
156 * required. The update operation is roughly categorized as a root
157 * update or intermediate layer update. When number of leaf nodes
158 * grow over a power of 2 then a new layer is added at the top of the
159 * tree and a new root node is initialized. The old node at the lower
160 * layer is connected to this. In an intermediate node update
161 * operation a new intermediate node is added to the required layer.
162 *
163 * Debugging: Debugging can be enabled by setting the verifyStack flag
164 * true. Debugging is implemented using a dummy stack that behaves in
165 * a naive way, using STL vectors (i.e each unique address is pushed
166 * on the top of an STL vector stack, and SD is returned as
167 * Infinity. If a non unique address is encountered then the previous
168 * entry in the STL vector is removed, all the entities above it are
169 * pushed down, and the address is pushed at the top of the stack).
170 *
171 * A printStack(int numOfEntitiesToPrint) is provided to print top n entities
172 * in both (tree and STL based dummy stack).
173 */
177class StackDistCalc : public SimObject
174class StackDistCalc
178{
179
180 private:
181
182 struct Node;
183
184 typedef std::map<uint64_t, Node*> IndexNodeMap;
185 typedef std::map<Addr, uint64_t> AddressIndexMap;
186 typedef std::vector<IndexNodeMap> TreeType;
187
188 /**
189 * Gets sum from the node upwards recursively till the root. This
190 * function is called first by getSumsLeavesToRoot, and then
191 * recursively calls itself.
192 *
193 * @param node pointer to the node which is updated
194 * @param from_left variable which says that the request arrived
195 * from the left
196 * @param sum_from_below Sum of left and right children below
197 * @param level level in the tree the calling node is located
198 * @param stack_dist stack distance of the node below
199 * @return The stack distance of the current address.
200 *
201 */
202 uint64_t getSum(Node* node, bool from_left, uint64_t sum_from_below,
203 uint64_t stack_dist, uint64_t level) const;
204
205 /**
206 * Gets the sum from the leaf node specified. This function
207 * is called by calcStackDist.
208 *
209 * @param node pointer to the node which is updated
210 * @return The stack distance of the current address.
211 *
212 */
213 uint64_t getSumsLeavesToRoot(Node* node) const;
214
215 /**
216 * Updates the nodes upwards recursively till the root.
217 * This function is first called by updateSumsLeavesToRoot,
218 * and then it recursively calls itself.
219 *
220 * @param node pointer to the node which is updated
221 * @param from_left variable which says that the request arrived
222 * from the left
223 * @param sum_from_below Sum of left and right children below
224 * @param level level in the tree the calling node is located
225 * @param stack_dist stack distance of the node below
226 * @param discard_node whether the calling node was discarded or not
227 * @return The stack distance of the current address.
228 *
229 */
230 uint64_t updateSum(Node* node,
231 bool from_left, uint64_t sum_from_below, uint64_t level,
232 uint64_t stack_dist, bool discard_node);
233
234 /**
235 * Updates the leaf nodes and nodes above. This function is
236 * called by the calcStackDistAndUpdate.
237 *
238 * @param node pointer to the node which is updated
239 * @param is_new_leaf is true if this is a newly added node
240 * @return The stack distance of the current address.
241 *
242 */
243 uint64_t updateSumsLeavesToRoot(Node* node, bool is_new_leaf);
244
245 /**
246 * updateTree is a tree balancing operation, which maintains the
247 * binary tree structure.
248 * This method is called whenever index%2 == 0 (i.e. every
249 * alternate cycle) The two main operation are :
250 * OP1. Moving the root node one layer up if index counter
251 * crosses power of 2
252 * OP2. Addition of intermediate nodes as and when required
253 * and linking them to their parents in the layer above.
254 */
255 void updateTree();
256
257 /**
258 * This method is used for verification purposes
259 * It recursively traverses upwards from the given node till
260 * the root to check if the ultimate parent node (root-node) points
261 * to null.
262 *
263 * @param node pointer to the node whose sanity is being checked
264 * @param level the level at which this node is located in the tree
265 *
266 */
267 void sanityCheckTree(const Node* node, uint64_t level = 0) const;
268
269 /**
175{
176
177 private:
178
179 struct Node;
180
181 typedef std::map<uint64_t, Node*> IndexNodeMap;
182 typedef std::map<Addr, uint64_t> AddressIndexMap;
183 typedef std::vector<IndexNodeMap> TreeType;
184
185 /**
186 * Gets sum from the node upwards recursively till the root. This
187 * function is called first by getSumsLeavesToRoot, and then
188 * recursively calls itself.
189 *
190 * @param node pointer to the node which is updated
191 * @param from_left variable which says that the request arrived
192 * from the left
193 * @param sum_from_below Sum of left and right children below
194 * @param level level in the tree the calling node is located
195 * @param stack_dist stack distance of the node below
196 * @return The stack distance of the current address.
197 *
198 */
199 uint64_t getSum(Node* node, bool from_left, uint64_t sum_from_below,
200 uint64_t stack_dist, uint64_t level) const;
201
202 /**
203 * Gets the sum from the leaf node specified. This function
204 * is called by calcStackDist.
205 *
206 * @param node pointer to the node which is updated
207 * @return The stack distance of the current address.
208 *
209 */
210 uint64_t getSumsLeavesToRoot(Node* node) const;
211
212 /**
213 * Updates the nodes upwards recursively till the root.
214 * This function is first called by updateSumsLeavesToRoot,
215 * and then it recursively calls itself.
216 *
217 * @param node pointer to the node which is updated
218 * @param from_left variable which says that the request arrived
219 * from the left
220 * @param sum_from_below Sum of left and right children below
221 * @param level level in the tree the calling node is located
222 * @param stack_dist stack distance of the node below
223 * @param discard_node whether the calling node was discarded or not
224 * @return The stack distance of the current address.
225 *
226 */
227 uint64_t updateSum(Node* node,
228 bool from_left, uint64_t sum_from_below, uint64_t level,
229 uint64_t stack_dist, bool discard_node);
230
231 /**
232 * Updates the leaf nodes and nodes above. This function is
233 * called by the calcStackDistAndUpdate.
234 *
235 * @param node pointer to the node which is updated
236 * @param is_new_leaf is true if this is a newly added node
237 * @return The stack distance of the current address.
238 *
239 */
240 uint64_t updateSumsLeavesToRoot(Node* node, bool is_new_leaf);
241
242 /**
243 * updateTree is a tree balancing operation, which maintains the
244 * binary tree structure.
245 * This method is called whenever index%2 == 0 (i.e. every
246 * alternate cycle) The two main operation are :
247 * OP1. Moving the root node one layer up if index counter
248 * crosses power of 2
249 * OP2. Addition of intermediate nodes as and when required
250 * and linking them to their parents in the layer above.
251 */
252 void updateTree();
253
254 /**
255 * This method is used for verification purposes
256 * It recursively traverses upwards from the given node till
257 * the root to check if the ultimate parent node (root-node) points
258 * to null.
259 *
260 * @param node pointer to the node whose sanity is being checked
261 * @param level the level at which this node is located in the tree
262 *
263 */
264 void sanityCheckTree(const Node* node, uint64_t level = 0) const;
265
266 /**
270 * A convenient way of refering to infinity.
271 */
272 static constexpr uint64_t Infinity = std::numeric_limits<uint64_t>::max();
273
274 /**
275 * Process the given address. If Mark is true then set the
276 * mark flag of the leaf node.
277 * This function returns the stack distance of the incoming
278 * address and the previous status of the mark flag.
279 *
280 * @param r_address The current address to process
281 * @param mark set the mark flag for the address.
282 * @return The stack distance of the current address and the mark flag.
283 */
284 std::pair<uint64_t , bool> calcStackDist(const Addr r_address,
285 bool mark = false);
286
287 /**
288 * Process the given address:
289 * - Lookup the tree for the given address
290 * - delete old node if found in tree
291 * - add a new node (if addNewNode flag is set)
292 * This function returns the stack distance of the incoming
293 * address and the status of the mark flag.
294 *
295 * @param r_address The current address to process
296 * @param addNewNode If true, a new node is added to the tree
297 * @return The stack distance of the current address and the mark flag.
298 */
299 std::pair<uint64_t, bool> calcStackDistAndUpdate(const Addr r_address,
300 bool addNewNode = true);
301
302 /**
303 * Return the counter for address accesses (unique and
304 * non-unique). This is further used to dump stats at
305 * regular intervals.
306 *
307 * @return The stack distance of the current address.
308 */
309 uint64_t getIndex() const { return index; }
310
311 /**
312 * Query depth of the tree (tree[0] represents leaf layer while
313 * tree[treeDepth] represents the root layer, all layers in
314 * between contain intermediate nodes)
315 *
316 * @return Tree depth
317 */
318 uint64_t getTreeDepth() const { return tree.size() - 1; }
319
320 /**
321 * Print the last n items on the stack.
322 * This method prints top n entries in the tree based implementation as
323 * well as dummy stack.
324 * @param n Number of entries to print
325 */
326 void printStack(int n = 5) const;
327
328 /**
329 * This is an alternative implementation of the stack-distance
330 * in a naive way. It uses simple STL vector to represent the stack.
331 * It can be used in parallel for debugging purposes.
332 * It is 10x slower than the tree based implemenation.
333 *
334 * @param r_address The current address to process
335 * @param update_stack Flag to indicate if stack should be updated
336 * @return Stack distance which is calculated by this alternative
337 * implementation
338 *
339 */
340 uint64_t verifyStackDist(const Addr r_address,
341 bool update_stack = false);
342
343 public:
267 * Return the counter for address accesses (unique and
268 * non-unique). This is further used to dump stats at
269 * regular intervals.
270 *
271 * @return The stack distance of the current address.
272 */
273 uint64_t getIndex() const { return index; }
274
275 /**
276 * Query depth of the tree (tree[0] represents leaf layer while
277 * tree[treeDepth] represents the root layer, all layers in
278 * between contain intermediate nodes)
279 *
280 * @return Tree depth
281 */
282 uint64_t getTreeDepth() const { return tree.size() - 1; }
283
284 /**
285 * Print the last n items on the stack.
286 * This method prints top n entries in the tree based implementation as
287 * well as dummy stack.
288 * @param n Number of entries to print
289 */
290 void printStack(int n = 5) const;
291
292 /**
293 * This is an alternative implementation of the stack-distance
294 * in a naive way. It uses simple STL vector to represent the stack.
295 * It can be used in parallel for debugging purposes.
296 * It is 10x slower than the tree based implemenation.
297 *
298 * @param r_address The current address to process
299 * @param update_stack Flag to indicate if stack should be updated
300 * @return Stack distance which is calculated by this alternative
301 * implementation
302 *
303 */
304 uint64_t verifyStackDist(const Addr r_address,
305 bool update_stack = false);
306
307 public:
308 StackDistCalc(bool verify_stack = false);
344
309
310 ~StackDistCalc();
311
345 /**
312 /**
346 * Convenience method to get the params when registering stats.
313 * A convenient way of refering to infinity.
347 */
314 */
348 const StackDistCalcParams* params() const
349 { return reinterpret_cast<const StackDistCalcParams*>(_params); }
315 static constexpr uint64_t Infinity = std::numeric_limits<uint64_t>::max();
350
316
351 StackDistCalc(const StackDistCalcParams* p);
352
317
353 ~StackDistCalc();
318 /**
319 * Process the given address. If Mark is true then set the
320 * mark flag of the leaf node.
321 * This function returns the stack distance of the incoming
322 * address and the previous status of the mark flag.
323 *
324 * @param r_address The current address to process
325 * @param mark set the mark flag for the address.
326 * @return The stack distance of the current address and the mark flag.
327 */
328 std::pair<uint64_t, bool> calcStackDist(const Addr r_address,
329 bool mark = false);
354
330
355 void regStats();
356
357 /**
331 /**
358 * Update the tree and the statistics.
332 * Process the given address:
333 * - Lookup the tree for the given address
334 * - delete old node if found in tree
335 * - add a new node (if addNewNode flag is set)
336 * This function returns the stack distance of the incoming
337 * address and the status of the mark flag.
359 *
338 *
360 * @param cmd Command from the packet
361 * @param addr Address to put on the stack
339 * @param r_address The current address to process
340 * @param addNewNode If true, a new node is added to the tree
341 * @return The stack distance of the current address and the mark flag.
362 */
342 */
363 void update(const MemCmd& cmd, Addr addr);
343 std::pair<uint64_t, bool> calcStackDistAndUpdate(const Addr r_address,
344 bool addNewNode = true);
364
365 private:
366
367 /**
368 * Node which takes form of Leaf, INode or Root
369 */
370 struct Node{
371 // Sum of the left children
372 uint64_t sumLeft;
373
374 // Sum of the right children
375 uint64_t sumRight;
376
377 // Flag to indicate that sumLeft has gone from non-zero value to 0
378 bool discardLeft;
379
380 // Flag to indicate that sumRight has gone from non-zero value to 0
381 bool discardRight;
382
383 // Index of the current element in the Map
384 uint64_t nodeIndex;
385
386 // Pointer to the parent
387 Node* parent;
388
389 // Flag to mark the node as the right/left child
390 bool isLeftNode;
391
392 /**
393 * Flag to indicate if this address is marked. Used in case
394 * where stack distance of a touched address is required.
395 */
396 bool isMarked;
397
398 /**
399 * The discard flags are false by default they become true if
400 * the node is reached again in a future lookup.
401 */
402 Node() : sumLeft(0), sumRight(0), discardLeft(false),
403 discardRight(false), nodeIndex(0),
404 parent(nullptr), isLeftNode(true), isMarked(false)
405 { }
406 };
407
408 /**
409 * Internal counter for address accesses (unique and non-unique)
410 * This counter increments everytime the calcStackDist() method is
411 * called. This counter is used as a key for the hash- map at the
412 * leaf layer. Practically at every call to the calculator this
413 * counter is incremented and a new leaf node is added in the tree
414 * at the leaf layer using this counter value as the key.
415 */
416 uint64_t index;
417
418 // Binary tree of partial sums
419 TreeType tree;
420
421 // Hash map which returns last seen index of each address
422 AddressIndexMap aiMap;
423
424 // Keeps count of number of the next unique index for each
425 // level in the tree
426 std::vector<uint64_t> nextIndex;
427
428 // Dummy Stack for verification
429 std::vector<uint64_t> stack;
430
431 // Flag to enable verification of stack. (Slows down the simulation)
432 const bool verifyStack;
345
346 private:
347
348 /**
349 * Node which takes form of Leaf, INode or Root
350 */
351 struct Node{
352 // Sum of the left children
353 uint64_t sumLeft;
354
355 // Sum of the right children
356 uint64_t sumRight;
357
358 // Flag to indicate that sumLeft has gone from non-zero value to 0
359 bool discardLeft;
360
361 // Flag to indicate that sumRight has gone from non-zero value to 0
362 bool discardRight;
363
364 // Index of the current element in the Map
365 uint64_t nodeIndex;
366
367 // Pointer to the parent
368 Node* parent;
369
370 // Flag to mark the node as the right/left child
371 bool isLeftNode;
372
373 /**
374 * Flag to indicate if this address is marked. Used in case
375 * where stack distance of a touched address is required.
376 */
377 bool isMarked;
378
379 /**
380 * The discard flags are false by default they become true if
381 * the node is reached again in a future lookup.
382 */
383 Node() : sumLeft(0), sumRight(0), discardLeft(false),
384 discardRight(false), nodeIndex(0),
385 parent(nullptr), isLeftNode(true), isMarked(false)
386 { }
387 };
388
389 /**
390 * Internal counter for address accesses (unique and non-unique)
391 * This counter increments everytime the calcStackDist() method is
392 * called. This counter is used as a key for the hash- map at the
393 * leaf layer. Practically at every call to the calculator this
394 * counter is incremented and a new leaf node is added in the tree
395 * at the leaf layer using this counter value as the key.
396 */
397 uint64_t index;
398
399 // Binary tree of partial sums
400 TreeType tree;
401
402 // Hash map which returns last seen index of each address
403 AddressIndexMap aiMap;
404
405 // Keeps count of number of the next unique index for each
406 // level in the tree
407 std::vector<uint64_t> nextIndex;
408
409 // Dummy Stack for verification
410 std::vector<uint64_t> stack;
411
412 // Flag to enable verification of stack. (Slows down the simulation)
413 const bool verifyStack;
433
434 // Disable the linear histograms
435 const bool disableLinearHists;
436
437 // Disable the logarithmic histograms
438 const bool disableLogHists;
439
440 // Reads linear histogram
441 Stats::Histogram readLinearHist;
442
443 // Reads logarithmic histogram
444 Stats::SparseHistogram readLogHist;
445
446 // Writes linear histogram
447 Stats::Histogram writeLinearHist;
448
449 // Writes logarithmic histogram
450 Stats::SparseHistogram writeLogHist;
451
452};
453
414};
415
416
454#endif //__STACK_DIST_CALC_HH__
417#endif //__STACK_DIST_CALC_HH__