/ libevmjit / ExecStats.cpp
ExecStats.cpp
 1  #include "ExecStats.h"
 2  
 3  #include <iostream>
 4  #include <iomanip>
 5  #include <cassert>
 6  
 7  #include "Utils.h"
 8  
 9  namespace dev
10  {
11  namespace evmjit
12  {
13  
14  void ExecStats::stateChanged(ExecState _state)
15  {
16  	if (!CHECK(m_state != ExecState::Finished))
17  		return;
18  
19  	auto now = clock::now();
20  	if (_state != ExecState::Started)
21  	{
22  		assert(time[(int)m_state] == ExecStats::duration::zero());
23  		time[(int)m_state] = now - m_tp;
24  	}
25  	m_state = _state;
26  	m_tp = now;
27  }
28  
29  namespace
30  {
31  struct StatsAgg
32  {
33  	using unit = std::chrono::microseconds;
34  	ExecStats::duration tot = ExecStats::duration::zero();
35  	ExecStats::duration min = ExecStats::duration::max();
36  	ExecStats::duration max = ExecStats::duration::zero();
37  	size_t count = 0;
38  
39  	void update(ExecStats::duration _d)
40  	{
41  		++count;
42  		tot += _d;
43  		min = _d < min ? _d : min;
44  		max = _d > max ? _d : max;
45  	}
46  
47  	void output(char const* _name, std::ostream& _os)
48  	{
49  		auto avg = tot / count;
50  		_os << std::setfill(' ')
51  			<< std::setw(12) << std::left  << _name
52  			<< std::setw(10) << std::right << std::chrono::duration_cast<unit>(tot).count()
53  			<< std::setw(10) << std::right << std::chrono::duration_cast<unit>(avg).count()
54  			<< std::setw(10) << std::right << std::chrono::duration_cast<unit>(min).count()
55  			<< std::setw(10) << std::right << std::chrono::duration_cast<unit>(max).count()
56  			<< std::endl;
57  	}
58  };
59  
60  char const* getExecStateName(ExecState _state)
61  {
62  	switch (_state)
63  	{
64  	case ExecState::Started: return "Start";
65  	case ExecState::CacheLoad: return "CacheLoad";
66  	case ExecState::CacheWrite: return "CacheWrite";
67  	case ExecState::Compilation: return "Compilation";
68  	case ExecState::Optimization: return "Optimization";
69  	case ExecState::CodeGen: return "CodeGen";
70  	case ExecState::Execution: return "Execution";
71  	case ExecState::Return: return "Return";
72  	case ExecState::Finished: return "Finish";
73  	}
74  	return nullptr;
75  }
76  }
77  
78  StatsCollector::~StatsCollector()
79  {
80  	if (stats.empty())
81  		return;
82  
83  	std::cout << "        [us]     total       avg       min       max\n";
84  	for (int i = 0; i < (int)ExecState::Finished; ++i)
85  	{
86  		StatsAgg agg;
87  		for (auto&& s : stats)
88  			agg.update(s->time[i]);
89  
90  		agg.output(getExecStateName(ExecState(i)), std::cout);
91  	}
92  }
93  
94  }
95  }