mem: Redesign the stack distance calculator as a probe

This changeset removes the stack distance calculator hooks from the
CommMonitor class and implements a stack distance calculator as a
memory system probe instead. The probe can be hooked up to any
component that exports probe points of the type ProbePoints::Packet.
This commit is contained in:
Andreas Sandberg 2015-08-04 10:29:13 +01:00
parent feded87fc9
commit 022e69e6de
11 changed files with 290 additions and 170 deletions

View file

@ -110,6 +110,3 @@ class CommMonitor(MemObject):
read_addr_mask = Param.Addr(MaxAddr, "Address mask for read address")
write_addr_mask = Param.Addr(MaxAddr, "Address mask for write address")
disable_addr_dists = Param.Bool(True, "Disable address distributions")
# optional stack distance calculator
stack_dist_calc = Param.StackDistCalc(NULL, "Stack distance calculator")

View file

@ -44,7 +44,6 @@ SimObject('ExternalMaster.py')
SimObject('ExternalSlave.py')
SimObject('MemObject.py')
SimObject('SimpleMemory.py')
SimObject('StackDistCalc.py')
SimObject('XBar.py')
Source('abstract_mem.cc')

View file

@ -55,7 +55,6 @@ CommMonitor::CommMonitor(Params* params)
samplePeriod(params->sample_period / SimClock::Float::s),
readAddrMask(params->read_addr_mask),
writeAddrMask(params->write_addr_mask),
stackDistCalc(params->stack_dist_calc),
system(params->system),
traceStream(nullptr),
stats(params)
@ -183,10 +182,6 @@ CommMonitor::recvAtomic(PacketPtr pkt)
{
ppPktReq->notify(pkt);
// do stack distance calculations if enabled
if (stackDistCalc)
stackDistCalc->update(pkt->cmd, pkt->getAddr());
// if tracing enabled, store the packet information
// to the trace stream
if (traceStream != NULL) {
@ -258,11 +253,6 @@ CommMonitor::recvTimingReq(PacketPtr pkt)
pkt->cmd = response_cmd;
}
// If successful and we are calculating stack distances, update
// the calculator
if (successful && stackDistCalc)
stackDistCalc->update(cmd, addr);
if (successful && traceStream != NULL) {
// Create a protobuf message representing the
// packet. Currently we do not preserve the flags in the

View file

@ -43,7 +43,6 @@
#include "base/statistics.hh"
#include "mem/mem_object.hh"
#include "mem/stack_dist_calc.hh"
#include "params/CommMonitor.hh"
#include "proto/protoio.hh"
#include "sim/probe/mem.hh"
@ -417,9 +416,6 @@ class CommMonitor : public MemObject
/** Address mask for sources of write accesses to be captured */
const Addr writeAddrMask;
/** Optional stack distance calculator */
StackDistCalc *const stackDistCalc;
/** The system in which the monitor lives */
System *const system;

View file

@ -41,3 +41,6 @@ Import('*')
SimObject('BaseMemProbe.py')
Source('base.cc')
SimObject('StackDistProbe.py')
Source('stack_dist.cc')

View file

@ -1,4 +1,4 @@
# Copyright (c) 2014 ARM Limited
# Copyright (c) 2014-2015 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
@ -34,13 +34,23 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Andreas Hansson
# Andreas Sandberg
from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
from BaseMemProbe import BaseMemProbe
class StackDistCalc(SimObject):
type = 'StackDistCalc'
cxx_header = "mem/stack_dist_calc.hh"
class StackDistProbe(BaseMemProbe):
type = 'StackDistProbe'
cxx_header = "mem/probes/stack_dist.hh"
system = Param.System(Parent.any,
"System to use when determining system cache "
"line size")
line_size = Param.Unsigned(Parent.cache_line_size,
"Cache line size in bytes (must be larger or "
"equal to the system's line size)")
# enable verification stack
verify = Param.Bool(False, "Verify behaviuor with reference implementation")

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2015 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 Sandberg
*/
#include "mem/probes/stack_dist.hh"
#include "params/StackDistProbe.hh"
#include "sim/system.hh"
StackDistProbe::StackDistProbe(StackDistProbeParams *p)
: BaseMemProbe(p),
lineSize(p->line_size),
disableLinearHists(p->disable_linear_hists),
disableLogHists(p->disable_log_hists),
calc(p->verify)
{
fatal_if(p->system->cacheLineSize() > p->line_size,
"The stack distance probe must use a cache line size that is "
"larger or equal to the system's cahce line size.");
}
void
StackDistProbe::regStats()
{
const StackDistProbeParams *p(
dynamic_cast<const StackDistProbeParams *>(params()));
assert(p);
using namespace Stats;
readLinearHist
.init(p->linear_hist_bins)
.name(name() + ".readLinearHist")
.desc("Reads linear distribution")
.flags(disableLinearHists ? nozero : pdf);
readLogHist
.init(p->log_hist_bins)
.name(name() + ".readLogHist")
.desc("Reads logarithmic distribution")
.flags(disableLogHists ? nozero : pdf);
writeLinearHist
.init(p->linear_hist_bins)
.name(name() + ".writeLinearHist")
.desc("Writes linear distribution")
.flags(disableLinearHists ? nozero : pdf);
writeLogHist
.init(p->log_hist_bins)
.name(name() + ".writeLogHist")
.desc("Writes logarithmic distribution")
.flags(disableLogHists ? nozero : pdf);
infiniteSD
.name(name() + ".infinity")
.desc("Number of requests with infinite stack distance")
.flags(nozero);
}
void
StackDistProbe::handleRequest(const PacketPtr &pkt)
{
// only capturing read and write requests (which allocate in the
// cache)
if (!pkt->isRead() && !pkt->isWrite())
return;
// Align the address to a cache line size
const Addr aligned_addr(roundDown(pkt->getAddr(), lineSize));
// Calculate the stack distance
const uint64_t sd(calc.calcStackDistAndUpdate(aligned_addr).first);
if (sd == StackDistCalc::Infinity) {
infiniteSD++;
return;
}
// Sample the stack distance of the address in linear bins
if (!disableLinearHists) {
if (pkt->isRead())
readLinearHist.sample(sd);
else
writeLinearHist.sample(sd);
}
if (!disableLogHists) {
int sd_lg2 = sd == 0 ? 1 : floorLog2(sd);
// Sample the stack distance of the address in log bins
if (pkt->isRead())
readLogHist.sample(sd_lg2);
else
writeLogHist.sample(sd_lg2);
}
}
StackDistProbe *
StackDistProbeParams::create()
{
return new StackDistProbe(this);
}

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2015 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 Sandberg
*/
#ifndef __MEM_PROBES_STACK_DIST_HH__
#define __MEM_PROBES_STACK_DIST_HH__
#include "mem/packet.hh"
#include "mem/probes/base.hh"
#include "mem/stack_dist_calc.hh"
#include "sim/stats.hh"
struct StackDistProbeParams;
class StackDistProbe : public BaseMemProbe
{
public:
StackDistProbe(StackDistProbeParams *params);
void regStats() M5_ATTR_OVERRIDE;
protected:
void handleRequest(const PacketPtr &pkt) M5_ATTR_OVERRIDE;
protected:
// Cache line size to simulate
const unsigned lineSize;
// Disable the linear histograms
const bool disableLinearHists;
// Disable the logarithmic histograms
const bool disableLogHists;
protected:
// Reads linear histogram
Stats::Histogram readLinearHist;
// Reads logarithmic histogram
Stats::SparseHistogram readLogHist;
// Writes linear histogram
Stats::Histogram writeLinearHist;
// Writes logarithmic histogram
Stats::SparseHistogram writeLogHist;
// Writes logarithmic histogram
Stats::Scalar infiniteSD;
protected:
StackDistCalc calc;
};
#endif //__MEM_PROBES_STACK_DIST_HH__

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 ARM Limited
* Copyright (c) 2014-2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@ -37,15 +37,16 @@
* Authors: Kanishk Sugand
*/
#include "mem/stack_dist_calc.hh"
#include "base/chunk_generator.hh"
#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)
StackDistCalc::StackDistCalc(bool verify_stack)
: index(0),
verifyStack(verify_stack)
{
// Instantiate a new root and leaf layer
// Map type variable, representing a layer in the tree
@ -91,38 +92,6 @@ StackDistCalc::~StackDistCalc()
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.
@ -632,39 +601,3 @@ StackDistCalc::printStack(int n) const
}
}
}
void
StackDistCalc::regStats()
{
using namespace Stats;
readLinearHist
.init(params()->linear_hist_bins)
.name(name() + ".readLinearHist")
.desc("Reads linear distribution")
.flags(disableLinearHists ? nozero : pdf);
readLogHist
.init(params()->log_hist_bins)
.name(name() + ".readLogHist")
.desc("Reads logarithmic distribution")
.flags(disableLogHists ? nozero : pdf);
writeLinearHist
.init(params()->linear_hist_bins)
.name(name() + ".writeLinearHist")
.desc("Writes linear distribution")
.flags(disableLinearHists ? nozero : pdf);
writeLogHist
.init(params()->log_hist_bins)
.name(name() + ".writeLogHist")
.desc("Writes logarithmic distribution")
.flags(disableLogHists ? nozero : pdf);
}
StackDistCalc*
StackDistCalcParams::create()
{
return new StackDistCalc(this);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014 ARM Limited
* Copyright (c) 2014-2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@ -41,14 +41,11 @@
#ifndef __MEM_STACK_DIST_CALC_HH__
#define __MEM_STACK_DIST_CALC_HH__
#include <limits>
#include <map>
#include <vector>
#include "base/types.hh"
#include "mem/packet.hh"
#include "params/StackDistCalc.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
/**
* The stack distance calculator is a passive object that merely
@ -174,7 +171,7 @@
* A printStack(int numOfEntitiesToPrint) is provided to print top n entities
* in both (tree and STL based dummy stack).
*/
class StackDistCalc : public SimObject
class StackDistCalc
{
private:
@ -266,39 +263,6 @@ class StackDistCalc : public SimObject
*/
void sanityCheckTree(const Node* node, uint64_t level = 0) const;
/**
* A convenient way of refering to infinity.
*/
static constexpr uint64_t Infinity = std::numeric_limits<uint64_t>::max();
/**
* Process the given address. If Mark is true then set the
* mark flag of the leaf node.
* This function returns the stack distance of the incoming
* address and the previous status of the mark flag.
*
* @param r_address The current address to process
* @param mark set the mark flag for the address.
* @return The stack distance of the current address and the mark flag.
*/
std::pair<uint64_t , bool> calcStackDist(const Addr r_address,
bool mark = false);
/**
* Process the given address:
* - Lookup the tree for the given address
* - delete old node if found in tree
* - add a new node (if addNewNode flag is set)
* This function returns the stack distance of the incoming
* address and the status of the mark flag.
*
* @param r_address The current address to process
* @param addNewNode If true, a new node is added to the tree
* @return The stack distance of the current address and the mark flag.
*/
std::pair<uint64_t, bool> calcStackDistAndUpdate(const Addr r_address,
bool addNewNode = true);
/**
* Return the counter for address accesses (unique and
* non-unique). This is further used to dump stats at
@ -341,26 +305,43 @@ class StackDistCalc : public SimObject
bool update_stack = false);
public:
/**
* Convenience method to get the params when registering stats.
*/
const StackDistCalcParams* params() const
{ return reinterpret_cast<const StackDistCalcParams*>(_params); }
StackDistCalc(const StackDistCalcParams* p);
StackDistCalc(bool verify_stack = false);
~StackDistCalc();
void regStats();
/**
* A convenient way of refering to infinity.
*/
static constexpr uint64_t Infinity = std::numeric_limits<uint64_t>::max();
/**
* Update the tree and the statistics.
* Process the given address. If Mark is true then set the
* mark flag of the leaf node.
* This function returns the stack distance of the incoming
* address and the previous status of the mark flag.
*
* @param cmd Command from the packet
* @param addr Address to put on the stack
* @param r_address The current address to process
* @param mark set the mark flag for the address.
* @return The stack distance of the current address and the mark flag.
*/
void update(const MemCmd& cmd, Addr addr);
std::pair<uint64_t, bool> calcStackDist(const Addr r_address,
bool mark = false);
/**
* Process the given address:
* - Lookup the tree for the given address
* - delete old node if found in tree
* - add a new node (if addNewNode flag is set)
* This function returns the stack distance of the incoming
* address and the status of the mark flag.
*
* @param r_address The current address to process
* @param addNewNode If true, a new node is added to the tree
* @return The stack distance of the current address and the mark flag.
*/
std::pair<uint64_t, bool> calcStackDistAndUpdate(const Addr r_address,
bool addNewNode = true);
private:
@ -430,25 +411,7 @@ class StackDistCalc : public SimObject
// Flag to enable verification of stack. (Slows down the simulation)
const bool verifyStack;
// Disable the linear histograms
const bool disableLinearHists;
// Disable the logarithmic histograms
const bool disableLogHists;
// Reads linear histogram
Stats::Histogram readLinearHist;
// Reads logarithmic histogram
Stats::SparseHistogram readLogHist;
// Writes linear histogram
Stats::Histogram writeLinearHist;
// Writes logarithmic histogram
Stats::SparseHistogram writeLogHist;
};
#endif //__STACK_DIST_CALC_HH__

View file

@ -57,8 +57,8 @@ system = System(cpu = cpu, physmem = SimpleMemory(),
# add a communication monitor, and also trace all the packets and
# calculate and verify stack distance
system.monitor = CommMonitor(trace_file = "monitor.ptrc.gz",
trace_enable = True,
stack_dist_calc = StackDistCalc(verify = True))
trace_enable = True)
system.monitor.stackdist = StackDistProbe(verify = True)
# connect the traffic generator to the bus via a communication monitor
system.cpu.port = system.monitor.slave