#include "ExecStats.h" #include #include #include #include "Utils.h" namespace dev { namespace eth { namespace jit { void ExecStats::stateChanged(ExecState _state) { if (!CHECK(m_state != ExecState::Finished)) return; auto now = clock::now(); if (_state != ExecState::Started) { assert(time[(int)m_state] == ExecStats::duration::zero()); time[(int)m_state] = now - m_tp; } m_state = _state; m_tp = now; } namespace { struct StatsAgg { using unit = std::chrono::microseconds; ExecStats::duration tot = ExecStats::duration::zero(); ExecStats::duration min = ExecStats::duration::max(); ExecStats::duration max = ExecStats::duration::zero(); size_t count = 0; void update(ExecStats::duration _d) { ++count; tot += _d; min = _d < min ? _d : min; max = _d > max ? _d : max; } void output(char const* _name, std::ostream& _os) { auto avg = tot / count; _os << std::setfill(' ') << std::setw(12) << std::left << _name << std::setw(10) << std::right << std::chrono::duration_cast(tot).count() << std::setw(10) << std::right << std::chrono::duration_cast(avg).count() << std::setw(10) << std::right << std::chrono::duration_cast(min).count() << std::setw(10) << std::right << std::chrono::duration_cast(max).count() << std::endl; } }; char const* getExecStateName(ExecState _state) { switch (_state) { case ExecState::Started: return "Start"; case ExecState::CacheLoad: return "CacheLoad"; case ExecState::CacheWrite: return "CacheWrite"; case ExecState::Compilation: return "Compilation"; case ExecState::CodeGen: return "CodeGen"; case ExecState::Execution: return "Execution"; case ExecState::Return: return "Return"; case ExecState::Finished: return "Finish"; } return nullptr; } } StatsCollector::~StatsCollector() { if (stats.empty()) return; std::cout << " [us] total avg min max\n"; for (int i = 0; i < (int)ExecState::Finished; ++i) { StatsAgg agg; for (auto&& s : stats) agg.update(s->time[i]); agg.output(getExecStateName(ExecState(i)), std::cout); } } } } }