mirror of
https://github.com/monero-project/monero.git
synced 2025-06-20 21:44:10 -04:00
Merge pull request #5102
1eef0565
performance_tests: better stats, and keep track of timing history (moneromooo-monero)
This commit is contained in:
commit
a28237c9ca
8 changed files with 638 additions and 62 deletions
|
@ -45,6 +45,7 @@ set(common_sources
|
|||
threadpool.cpp
|
||||
updates.cpp
|
||||
aligned.c
|
||||
timings.cc
|
||||
combinator.cpp)
|
||||
|
||||
if (STACK_TRACE)
|
||||
|
@ -84,6 +85,7 @@ set(common_private_headers
|
|||
threadpool.h
|
||||
updates.h
|
||||
aligned.h
|
||||
timings.h
|
||||
combinator.h)
|
||||
|
||||
monero_private_headers(common
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
void resume();
|
||||
void reset();
|
||||
uint64_t value() const;
|
||||
operator uint64_t() const { return value(); }
|
||||
|
||||
protected:
|
||||
uint64_t ticks;
|
||||
|
|
125
src/common/timings.cc
Normal file
125
src/common/timings.cc
Normal file
|
@ -0,0 +1,125 @@
|
|||
#include <string.h>
|
||||
#include <error.h>
|
||||
#include <time.h>
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "misc_log_ex.h"
|
||||
#include "timings.h"
|
||||
|
||||
#define N_EXPECTED_FIELDS (8+11)
|
||||
|
||||
TimingsDatabase::TimingsDatabase()
|
||||
{
|
||||
}
|
||||
|
||||
TimingsDatabase::TimingsDatabase(const std::string &filename):
|
||||
filename(filename)
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
TimingsDatabase::~TimingsDatabase()
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
bool TimingsDatabase::load()
|
||||
{
|
||||
instances.clear();
|
||||
|
||||
if (filename.empty())
|
||||
return true;
|
||||
|
||||
FILE *f = fopen(filename.c_str(), "r");
|
||||
if (!f)
|
||||
{
|
||||
MDEBUG("Failed to load timings file " << filename << ": " << strerror(errno));
|
||||
return false;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
char s[4096];
|
||||
if (!fgets(s, sizeof(s), f))
|
||||
break;
|
||||
char *tab = strchr(s, '\t');
|
||||
if (!tab)
|
||||
{
|
||||
MWARNING("Bad format: no tab found");
|
||||
continue;
|
||||
}
|
||||
const std::string name = std::string(s, tab - s);
|
||||
std::vector<std::string> fields;
|
||||
char *ptr = tab + 1;
|
||||
boost::split(fields, ptr, boost::is_any_of(" "));
|
||||
if (fields.size() != N_EXPECTED_FIELDS)
|
||||
{
|
||||
MERROR("Bad format: wrong number of fields: got " << fields.size() << " expected " << N_EXPECTED_FIELDS);
|
||||
continue;
|
||||
}
|
||||
|
||||
instance i;
|
||||
|
||||
unsigned int idx = 0;
|
||||
i.t = atoi(fields[idx++].c_str());
|
||||
i.npoints = atoi(fields[idx++].c_str());
|
||||
i.min = atof(fields[idx++].c_str());
|
||||
i.max = atof(fields[idx++].c_str());
|
||||
i.mean = atof(fields[idx++].c_str());
|
||||
i.median = atof(fields[idx++].c_str());
|
||||
i.stddev = atof(fields[idx++].c_str());
|
||||
i.npskew = atof(fields[idx++].c_str());
|
||||
i.deciles.reserve(11);
|
||||
for (int n = 0; n < 11; ++n)
|
||||
{
|
||||
i.deciles.push_back(atoi(fields[idx++].c_str()));
|
||||
}
|
||||
instances.insert(std::make_pair(name, i));
|
||||
}
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TimingsDatabase::save()
|
||||
{
|
||||
if (filename.empty())
|
||||
return true;
|
||||
|
||||
FILE *f = fopen(filename.c_str(), "w");
|
||||
if (!f)
|
||||
{
|
||||
MERROR("Failed to write to file " << filename << ": " << strerror(errno));
|
||||
return false;
|
||||
}
|
||||
for (const auto &i: instances)
|
||||
{
|
||||
fprintf(f, "%s", i.first.c_str());
|
||||
fprintf(f, "\t%lu", (unsigned long)i.second.t);
|
||||
fprintf(f, " %zu", i.second.npoints);
|
||||
fprintf(f, " %f", i.second.min);
|
||||
fprintf(f, " %f", i.second.max);
|
||||
fprintf(f, " %f", i.second.mean);
|
||||
fprintf(f, " %f", i.second.median);
|
||||
fprintf(f, " %f", i.second.stddev);
|
||||
fprintf(f, " %f", i.second.npskew);
|
||||
for (uint64_t v: i.second.deciles)
|
||||
fprintf(f, " %lu", (unsigned long)v);
|
||||
fputc('\n', f);
|
||||
}
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<TimingsDatabase::instance> TimingsDatabase::get(const char *name) const
|
||||
{
|
||||
std::vector<instance> ret;
|
||||
auto range = instances.equal_range(name);
|
||||
for (auto i = range.first; i != range.second; ++i)
|
||||
ret.push_back(i->second);
|
||||
std::sort(ret.begin(), ret.end(), [](const instance &e0, const instance &e1){ return e0.t < e1.t; });
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TimingsDatabase::add(const char *name, const instance &i)
|
||||
{
|
||||
instances.insert(std::make_pair(name, i));
|
||||
}
|
34
src/common/timings.h
Normal file
34
src/common/timings.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
class TimingsDatabase
|
||||
{
|
||||
public:
|
||||
struct instance
|
||||
{
|
||||
time_t t;
|
||||
size_t npoints;
|
||||
double min, max, mean, median, stddev, npskew;
|
||||
std::vector<uint64_t> deciles;
|
||||
};
|
||||
|
||||
public:
|
||||
TimingsDatabase();
|
||||
TimingsDatabase(const std::string &filename);
|
||||
~TimingsDatabase();
|
||||
|
||||
std::vector<instance> get(const char *name) const;
|
||||
void add(const char *name, const instance &data);
|
||||
|
||||
private:
|
||||
bool load();
|
||||
bool save();
|
||||
|
||||
private:
|
||||
std::string filename;
|
||||
std::multimap<std::string, instance> instances;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue