changeset da37aec3ed1a in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=da37aec3ed1a
description:
        mem: Add a stack distance calculator

        This patch adds a stand-alone stack distance calculator. The stack
        distance calculator is a passive SimObject that observes the addresses
        passed to it. It calculates stack distances (LRU Distances) of
        incoming addresses based on the partial sum hierarchy tree algorithm
        described by Alamasi et al. http://doi.acm.org/10.1145/773039.773043.

        For each transaction a hashtable look-up is performed. At every
        non-unique transaction the tree is traversed from the leaf at the
        returned index to the root, the old node is deleted from the tree, and
        the sums (to the right) are collected and decremented. The collected
        sum represets the stack distance of the found node. At every unique
        transaction the stack distance is returned as
        numeric_limits<uint64>::max().

        In addition to the basic stack distance calculation, a feature to mark
        an old node in the tree is added. This is useful if it is required to
        see the reuse pattern. For example, Writebacks to the lower level
        (e.g. membus from L2), can be marked instead of being removed from the
        stack (isMarked flag of Node set to True). And then later if this same
        address is accessed (by L1), the value of the isMarked flag would be
        True. This gives some insight on how the Writeback policy of the
        lower level affect the read/write accesses in an application.

        Debugging is enabled by setting the verify flag to true. Debugging is
        implemented using a dummy stack that behaves in a naive way, using STL
        vectors. Note that this has a large impact on run time.

diffstat:

 src/mem/SConscript         |    4 +-
 src/mem/StackDistCalc.py   |   54 +++
 src/mem/stack_dist_calc.cc |  670 +++++++++++++++++++++++++++++++++++++++++++++
 src/mem/stack_dist_calc.hh |  454 ++++++++++++++++++++++++++++++
 4 files changed, 1181 insertions(+), 1 deletions(-)

diffs (truncated from 1218 to 300 lines):

diff -r 9d0aef7a9b2e -r da37aec3ed1a src/mem/SConscript
--- a/src/mem/SConscript        Tue Dec 23 09:31:18 2014 -0500
+++ b/src/mem/SConscript        Tue Dec 23 09:31:18 2014 -0500
@@ -44,6 +44,7 @@
 SimObject('ExternalSlave.py')
 SimObject('MemObject.py')
 SimObject('SimpleMemory.py')
+SimObject('StackDistCalc.py')
 SimObject('XBar.py')
 
 Source('abstract_mem.cc')
@@ -64,6 +65,7 @@
 Source('physical.cc')
 Source('simple_mem.cc')
 Source('snoop_filter.cc')
+Source('stack_dist_calc.cc')
 Source('tport.cc')
 Source('xbar.cc')
 
@@ -101,7 +103,7 @@
 DebugFlag('MMU')
 DebugFlag('MemoryAccess')
 DebugFlag('PacketQueue')
-
+DebugFlag('StackDist')
 DebugFlag("DRAMSim2")
 
 DebugFlag("MemChecker")
diff -r 9d0aef7a9b2e -r da37aec3ed1a src/mem/StackDistCalc.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/StackDistCalc.py  Tue Dec 23 09:31:18 2014 -0500
@@ -0,0 +1,54 @@
+# Copyright (c) 2014 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder.  You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Andreas Hansson
+
+from m5.SimObject import SimObject
+from m5.params import *
+
+class StackDistCalc(SimObject):
+    type = 'StackDistCalc'
+    cxx_header = "mem/stack_dist_calc.hh"
+
+    # enable verification stack
+    verify = Param.Bool(False, "Verify behaviuor with reference 
implementation")
+
+    # linear histogram bins and enable/disable
+    linear_hist_bins = Param.Unsigned('16', "Bins in linear histograms")
+    disable_linear_hists = Param.Bool(False, "Disable linear histograms")
+
+    # logarithmic histogram bins and enable/disable
+    log_hist_bins = Param.Unsigned('32', "Bins in logarithmic histograms")
+    disable_log_hists = Param.Bool(False, "Disable logarithmic histograms")
diff -r 9d0aef7a9b2e -r da37aec3ed1a src/mem/stack_dist_calc.cc
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mem/stack_dist_calc.cc        Tue Dec 23 09:31:18 2014 -0500
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Kanishk Sugand
+ */
+
+#include "base/intmath.hh"
+#include "base/trace.hh"
+#include "debug/StackDist.hh"
+#include "mem/stack_dist_calc.hh"
+
+StackDistCalc::StackDistCalc(const StackDistCalcParams* p) :
+    SimObject(p), index(0), verifyStack(p->verify),
+    disableLinearHists(p->disable_linear_hists),
+    disableLogHists(p->disable_log_hists)
+{
+    // Instantiate a new root and leaf layer
+    // Map type variable, representing a layer in the tree
+    IndexNodeMap tree_level;
+
+    // Initialize tree count for leaves
+    nextIndex.push_back(0);
+
+    // Add the initial leaf layer to the tree
+    tree.push_back(tree_level);
+
+    // Create a root node. Node type variable in the topmost layer
+    Node* root_node = new Node();
+
+    // Initialize tree count for root
+    nextIndex.push_back(1);
+
+    // Add the empty root layer to the tree
+    tree.push_back(tree_level);
+
+    // Add the initial root to the tree
+    tree[1][root_node->nodeIndex] = root_node;
+}
+
+StackDistCalc::~StackDistCalc()
+{
+    // Walk through each layer and destroy the nodes
+    for (auto& layer : tree) {
+        for (auto& index_node : layer) {
+            // each map entry contains an index and a node
+            delete index_node.second;
+        }
+        // Clear each layer in the tree
+        layer.clear();
+    }
+
+    // Clear the tree
+    tree.clear();
+    aiMap.clear();
+    nextIndex.clear();
+
+    // For verification
+    stack.clear();
+}
+
+void
+StackDistCalc::update(const MemCmd& cmd, Addr addr)
+{
+    // only capturing read and write requests (which allocate in the
+    // cache)
+    if (cmd.isRead() || cmd.isWrite()) {
+        auto returnType = calcStackDistAndUpdate(addr);
+
+        uint64_t stackDist = returnType.first;
+
+        if (stackDist != Infinity) {
+            // Sample the stack distance of the address in linear bins
+            if (!disableLinearHists) {
+                if (cmd.isRead())
+                    readLinearHist.sample(stackDist);
+                else
+                    writeLinearHist.sample(stackDist);
+            }
+
+            if (!disableLogHists) {
+                int stackDistLog2 = stackDist == 0 ? 1 : floorLog2(stackDist);
+
+                // Sample the stack distance of the address in log bins
+                if (cmd.isRead())
+                    readLogHist.sample(stackDistLog2);
+                else
+                    writeLogHist.sample(stackDistLog2);
+            }
+        }
+    }
+}
+
+// The updateSum method is a recursive function which updates
+// the node sums till the root. It also deletes the nodes that
+// are not used anymore.
+uint64_t
+StackDistCalc::updateSum(Node* node, bool from_left,
+                         uint64_t sum_from_below, uint64_t level,
+                         uint64_t stack_dist, bool discard_node)
+{
+    ++level;
+
+    // Make a copy of the node variables and work on them
+    // as a node may be deleted by this function
+    uint64_t node_sum_l = node->sumLeft;
+    uint64_t node_sum_r = node->sumRight;
+    bool node_left = node->isLeftNode;
+    bool node_discard_left = node->discardLeft;
+    bool node_discard_right = node->discardRight;
+    uint64_t node_n_index = node->nodeIndex;
+    Node* node_parent_ptr = node->parent;
+
+    // For verification
+    if (verifyStack) {
+        // This sanity check makes sure that the left_sum and
+        // right_sum of the node is not greater than the
+        // maximum possible value given by the leaves below it
+        // for example a node in layer 3 (tree[3]) can at most
+        // have 8 leaves (4 to the left and 4 to the right)
+        // thus left_sum and right_sum should be <= 4
+        panic_if(node_sum_l > (1 << (level - 1)),
+                 "Error in sum left of level %ul, node index %ull, "
+                 "Sum =  %ull \n", level, node_n_index, node_sum_l);
+
+        panic_if(node_sum_r > (1 << (level - 1)),
+                 "Error in sum right of level %ul, node index %ull, "
+                 "Sum =  %ull \n", level, node_n_index, node_sum_r);
+    }
+
+    // Update the left sum or the right sum depending on the
+    // from_left flag. Variable stack_dist is updated only
+    // when arriving from Left.
+    if (from_left) {
+        // update sumLeft
+        node_sum_l = sum_from_below;
+        stack_dist +=  node_sum_r;
+    } else {
+        // update sum_r
+        node_sum_r = sum_from_below;
+    }
+
+    // sum_from_below == 0 can be a leaf discard operation
+    if (discard_node && !sum_from_below) {
+        if (from_left)
+            node_discard_left = true;
+        else
+            node_discard_right = true;
+    }
+
+    // Update the node variables with new values
+    node->nodeIndex = node_n_index;
+    node->sumLeft = node_sum_l;
+    node->sumRight = node_sum_r;
+    node->isLeftNode = node_left;
+    node->discardLeft = node_discard_left;
+    node->discardRight = node_discard_right;
+
+    // Delete the node if it is not required anymore
+    if (node_discard_left && node_discard_right &&
+        discard_node && node_parent_ptr && !sum_from_below) {
+        delete node;
+        tree[level].erase(node_n_index);
+        discard_node = true;
+    } else {
+        // propogate discard_node as false upwards if the
+        // above conditions are not met.
+        discard_node = false;
+    }
+
+    // Recursively call the updateSum operation till the
+    // root node is reached
+    if (node_parent_ptr) {
+        stack_dist = updateSum(node_parent_ptr, node_left,
+                               node_sum_l + node_sum_r,
+                               level, stack_dist, discard_node);
+    }
+
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to