-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmessurement.h
148 lines (119 loc) · 3.53 KB
/
messurement.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef MESSUREMENT_H
#define MESSUREMENT_H
#include <cstdint>
#include <limits>
#include <array>
#include <chrono>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
#include "config.h"
template<size_t C> class messurement
{
private:
std::array<double,C> data{}; //preinitialized Array
size_t index;
uint8_t valid;
double value;
double min;
double mean;
double max;
std::chrono::high_resolution_clock::time_point hrt1;
std::chrono::high_resolution_clock::time_point hrt2;
public:
messurement():index(0),valid(0),
value(0),min(std::numeric_limits<double>::max()),mean(DINTERVAL),max(0),
hrt1(std::chrono::high_resolution_clock::now()),hrt2(std::chrono::high_resolution_clock::now()){
return;
}
void take(){
//Take current Time
hrt2 = std::chrono::high_resolution_clock::now();
//Messure Precision with stdlib
std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(hrt2 - hrt1);
hrt1 = hrt2; //Prepare next cycle
value = time_span.count();
data[index++] = value;
if(RUNTIME_EVAL){
if(valid==SKIP_CYCLES){
min = std::numeric_limits<double>::max();
max = 0;
}
//Monitor Min and Max
if((valid>SKIP_CYCLES) && (value<min)){
min = value;
}
if((valid>SKIP_CYCLES) && (value>max)){
max = value;
}
//Calculate Mean Cycle Time
if(valid>0){
//if(valid>SKIP_CYCLES){
mean = mean + ((value - mean)/2);
}
//Prepare next cycle
if(valid<=SKIP_CYCLES)++valid;
}
return;
}
void result_cycle(struct timespec& ts, std::stringstream& ss){
if(RUNTIME_EVAL && LOG_CYCLES){
ss << std::scientific;
ss.precision(6);
ss << "sec: " << std::setw(8) << ts.tv_sec << " - nsec: " << std::setw(10) << ts.tv_nsec << " --> "
<< std::setw(11) << value << "[s]" << " --> "
<< std::setw(11) << min << " [s]" << " | "
<< std::setw(11) << mean << " [s]" << " | "
<< std::setw(11) << max << " [s]" << " { "
<< ((value>DINTERVAL)?("++"):("--")) << " } " << "\n";
}
return;
}
void result_offline(std::stringstream& ss){
ss << std::scientific;
ss.precision(6);
uint8_t valid = 0;
for(double _v:data){
//Monitor Min and Max
if((valid>=1) && (_v<min)){
min = _v;
}
if((valid>=1) && (_v>max)){
max = _v;
}
//Calculate Mean Cycle Time
mean = mean + ((_v - mean)/2);
ss << std::setw(11) << _v << "[s]" << " --> "
<< std::setw(11) << min << " [s]" << " | "
<< std::setw(11) << mean << " [s]" << " | "
<< std::setw(11) << max << " [s]" << " { "
<< ((_v>DINTERVAL)?("++"):("--")) << " } " << "\n";
valid = uint8_t(valid<<1) | uint8_t(1); //Just prevent <1 (no efficency needed)
}
return;
}
void result_histogram(std::stringstream& ss){
constexpr size_t const sidebins = 10;
std::array<uint32_t,2*sidebins+1> hist{};
double binsize = 0.005; //2.5%
for(double _v:data){
double x = _v - DINTERVAL;
bool slower = (x<0)?(true):(false);
x=std::abs(x);
double y = x / (DINTERVAL*binsize);
size_t z = size_t(std::lround(y));
if(slower) z+=sidebins;
else z = (sidebins+1)-z;
++hist[z%hist.size()];
}
//Simple List Output
ss << "|";
for(uint32_t _v:hist){
ss << _v << "|";
}
ss << "\n";
return;
}
};
#endif // MESSUREMENT_H