tools: added compute-hops and dump-hops tools
As these tools work closely together with fail components, its easiest, to build them in this context. As these tools don't really matter for fail use, they might never be pushed to the master branch. Change-Id: I8c8bd80376d0475f08a531a995d829e85032371b
This commit is contained in:
172
tools/compute-hops/ResultCollector.cc
Normal file
172
tools/compute-hops/ResultCollector.cc
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* StatisticsCollector.cc
|
||||
*
|
||||
* Created on: 21.08.2013
|
||||
* Author: lrade
|
||||
*/
|
||||
|
||||
#include "ResultCollector.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "comm/InjectionPointHopsMessage.pb.h"
|
||||
|
||||
// #include <proc/readproc.h>
|
||||
|
||||
using std::hex;
|
||||
using std::dec;
|
||||
|
||||
char separator = ' ';
|
||||
|
||||
extern std::ofstream g_cp_ofstream;
|
||||
|
||||
extern fail::Logger LOG;
|
||||
|
||||
void
|
||||
ResultCollector::setProtoOStream(ProtoOStream* protoOStream)
|
||||
{
|
||||
ps = protoOStream;
|
||||
}
|
||||
|
||||
unsigned int calculate_costs(std::vector<result_tuple >& res)
|
||||
{
|
||||
std::vector<result_tuple>::iterator it = res.begin();
|
||||
std::vector<result_tuple>::iterator it_ahead = res.begin();
|
||||
it_ahead++;
|
||||
|
||||
// Cost COST_CHANGE for first hop
|
||||
// Costs of all following hops are calculated only on basis of
|
||||
// difference between two consecutive hop_positions
|
||||
unsigned int costs = COST_CHANGE;
|
||||
|
||||
while (it != res.end() && it_ahead != res.end()) {
|
||||
if (it->first == it_ahead->first) {
|
||||
costs += COST_NO_CHANGE;
|
||||
} else {
|
||||
costs += COST_CHANGE;
|
||||
}
|
||||
it_ahead++;
|
||||
it++;
|
||||
}
|
||||
|
||||
return costs;
|
||||
}
|
||||
|
||||
void
|
||||
ResultCollector::addResult(std::vector<result_tuple >& res, unsigned int costs)
|
||||
{
|
||||
m_result_size++;
|
||||
|
||||
// Costs not calculated in hop calculator (e.g. dijkstra)? => Do it here
|
||||
if (costs == 0) {
|
||||
costs = calculate_costs(res);
|
||||
}
|
||||
|
||||
if (m_output_mode == OUTPUT_COSTS) {
|
||||
m_ostream << m_res_count++ << separator << costs << '\n';
|
||||
} else if (m_output_mode == OUTPUT_RESULT) {
|
||||
if (ps) {
|
||||
InjectionPointMessage hc;
|
||||
hc.set_costs(costs);
|
||||
hc.set_target_trace_position(res.back().second);
|
||||
// If checkpoint at beginning of hop-chain, add its id to InjectionPointMessage
|
||||
std::vector<result_tuple >::iterator it_hop = res.begin();
|
||||
if (it_hop != res.end() && it_hop->first.second == ACCESS_CHECKPOINT) {
|
||||
hc.set_checkpoint_id(it_hop->first.first);
|
||||
it_hop++;
|
||||
}
|
||||
|
||||
for(;it_hop != res.end();
|
||||
it_hop++) {
|
||||
InjectionPointMessage_Hops *hop = hc.add_hops();
|
||||
hop->set_address(it_hop->first.first);
|
||||
|
||||
enum InjectionPointMessage_Hops_AccessType at;
|
||||
switch (it_hop->first.second) {
|
||||
case ACCESS_NONE:
|
||||
at = InjectionPointMessage_Hops_AccessType_EXECUTE;
|
||||
break;
|
||||
case ACCESS_READ:
|
||||
at = InjectionPointMessage_Hops_AccessType_READ;
|
||||
break;
|
||||
case ACCESS_WRITE:
|
||||
at = InjectionPointMessage_Hops_AccessType_WRITE;
|
||||
break;
|
||||
case ACCESS_READORWRITE:
|
||||
LOG << "ReadOrWrite memory access event not yet"
|
||||
" covered" << std::endl;
|
||||
exit(-1);
|
||||
break;
|
||||
case ACCESS_CHECKPOINT:
|
||||
LOG << "Checkpoint not allowed after beginning of hop chain" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
hop->set_accesstype(at);
|
||||
}
|
||||
ps->writeMessage(&hc);
|
||||
} else {
|
||||
for(std::vector<result_tuple >::iterator it_hop = res.begin();
|
||||
it_hop != res.end();
|
||||
it_hop++) {
|
||||
address_t add = it_hop->first.first;
|
||||
mem_access_type_e mem_acc_type = it_hop->first.second;
|
||||
std::string prefix = (mem_acc_type == ACCESS_READ)?"R":((mem_acc_type == ACCESS_WRITE)?"W":((mem_acc_type == ACCESS_NONE)?"X":((mem_acc_type == ACCESS_CHECKPOINT)?"C":"")));
|
||||
m_ostream << prefix << hex << add << dec << separator;
|
||||
}
|
||||
|
||||
if (res.size() > 0)
|
||||
m_ostream << '\n';
|
||||
}
|
||||
} else if (m_output_mode == OUTPUT_STATISTICS) {
|
||||
// Calculate mean
|
||||
// http://www.heikohoffmann.de/htmlthesis/node134.html
|
||||
// c(t+1) = c(t) + (1/(t+1))*(x - c(t))
|
||||
m_it_mean_costs = m_it_mean_costs + (1/(double)m_result_size)*((double)costs-m_it_mean_costs);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ResultCollector::addCheckpoint(unsigned int pos)
|
||||
{
|
||||
g_cp_ofstream << m_checkpoint_count++ << separator << pos << '\n';
|
||||
}
|
||||
|
||||
void
|
||||
ResultCollector::startTimer()
|
||||
{
|
||||
m_timer.startTimer();
|
||||
}
|
||||
|
||||
void
|
||||
ResultCollector::stopTimer()
|
||||
{
|
||||
m_timer.stopTimer();
|
||||
}
|
||||
|
||||
void
|
||||
ResultCollector::setMaxMemUsage()
|
||||
{
|
||||
// struct proc_t usage;
|
||||
// look_up_our_self(&usage);
|
||||
// m_mem_usage = usage.vsize;
|
||||
}
|
||||
|
||||
void
|
||||
ResultCollector::finish()
|
||||
{
|
||||
// Print results if buffered
|
||||
|
||||
// Print statistics
|
||||
if (m_output_mode == OUTPUT_STATISTICS) {
|
||||
|
||||
m_ostream << m_result_size << separator << m_timer.getRuntimeAsDouble() << separator
|
||||
<< m_mem_usage << separator << m_it_mean_costs << separator << m_checkpoint_count << '\n';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user