blob: 9db1d489c24a558f25044b7a3947819b2ff139fb [file] [log] [blame]
/*
* Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
* All rights reserved.
*
* 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.
*/
#include "mem/ruby/profiler/StoreTrace.hh"
#include "sim/core.hh"
using namespace std;
bool StoreTrace::s_init = false; // Total number of store lifetimes of
// all lines
int64_t StoreTrace::s_total_samples = 0; // Total number of store
// lifetimes of all lines
Histogram* StoreTrace::s_store_count_ptr = NULL;
Histogram* StoreTrace::s_store_first_to_stolen_ptr = NULL;
Histogram* StoreTrace::s_store_last_to_stolen_ptr = NULL;
Histogram* StoreTrace::s_store_first_to_last_ptr = NULL;
StoreTrace::StoreTrace(Addr addr)
: m_store_count(-1), m_store_first_to_stolen(-1),
m_store_last_to_stolen(-1), m_store_first_to_last(-1)
{
StoreTrace::initSummary();
m_addr = addr;
m_total_samples = 0;
// Really -1 isn't valid, so this will trigger the initilization code
m_last_writer = -1;
m_stores_this_interval = 0;
}
StoreTrace::~StoreTrace()
{
}
void
StoreTrace::print(ostream& out) const
{
out << m_addr
<< " total_samples: " << m_total_samples << endl
<< "store_count: " << m_store_count << endl
<< "store_first_to_stolen: " << m_store_first_to_stolen << endl
<< "store_last_to_stolen: " << m_store_last_to_stolen << endl
<< "store_first_to_last: " << m_store_first_to_last << endl;
}
void
StoreTrace::initSummary()
{
if (!s_init) {
s_total_samples = 0;
s_store_count_ptr = new Histogram(-1);
s_store_first_to_stolen_ptr = new Histogram(-1);
s_store_last_to_stolen_ptr = new Histogram(-1);
s_store_first_to_last_ptr = new Histogram(-1);
}
s_init = true;
}
void
StoreTrace::printSummary(ostream& out)
{
out << "total_samples: " << s_total_samples << endl;
out << "store_count: " << (*s_store_count_ptr) << endl;
out << "store_first_to_stolen: " << (*s_store_first_to_stolen_ptr) << endl;
out << "store_last_to_stolen: " << (*s_store_last_to_stolen_ptr) << endl;
out << "store_first_to_last: " << (*s_store_first_to_last_ptr) << endl;
}
void
StoreTrace::clearSummary()
{
StoreTrace::initSummary();
s_total_samples = 0;
s_store_count_ptr->clear();
s_store_first_to_stolen_ptr->clear();
s_store_last_to_stolen_ptr->clear();
s_store_first_to_last_ptr->clear();
}
void
StoreTrace::store(NodeID node)
{
Tick current = curTick();
assert((m_last_writer == -1) || (m_last_writer == node));
m_last_writer = node;
if (m_last_writer == -1) {
assert(m_stores_this_interval == 0);
}
if (m_stores_this_interval == 0) {
// A new proessor just wrote the line, so reset the stats
m_first_store = current;
}
m_last_store = current;
m_stores_this_interval++;
}
void
StoreTrace::downgrade(NodeID node)
{
if (node == m_last_writer) {
Tick current = curTick();
assert(m_stores_this_interval != 0);
assert(m_last_store != 0);
assert(m_first_store != 0);
assert(m_last_writer != -1);
// Per line stats
m_store_first_to_stolen.add(current - m_first_store);
m_store_count.add(m_stores_this_interval);
m_store_last_to_stolen.add(current - m_last_store);
m_store_first_to_last.add(m_last_store - m_first_store);
m_total_samples++;
// Global stats
assert(s_store_first_to_stolen_ptr != NULL);
s_store_first_to_stolen_ptr->add(current - m_first_store);
s_store_count_ptr->add(m_stores_this_interval);
s_store_last_to_stolen_ptr->add(current - m_last_store);
s_store_first_to_last_ptr->add(m_last_store - m_first_store);
s_total_samples++;
// Initilize for next go round
m_stores_this_interval = 0;
m_last_store = 0;
m_first_store = 0;
m_last_writer = -1;
}
}