forked from learning-process/parallel_programming_course
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathperformance.hpp
More file actions
133 lines (119 loc) · 4.24 KB
/
performance.hpp
File metadata and controls
133 lines (119 loc) · 4.24 KB
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
#pragma once
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <memory>
#include <sstream>
#include <stdexcept>
#include <string>
#include "task/include/task.hpp"
#include "util/include/util.hpp"
namespace ppc::performance {
inline double DefaultTimer() {
return -1.0;
}
struct PerfAttr {
/// @brief Number of times the task is run for performance evaluation.
uint64_t num_running = 5;
/// @brief Timer function returning current time in seconds.
/// @cond
std::function<double()> current_timer = DefaultTimer;
/// @endcond
};
struct PerfResults {
/// @brief Measured execution time in seconds.
double time_sec = 0.0;
enum class TypeOfRunning : uint8_t {
kPipeline,
kTaskRun,
kNone,
};
TypeOfRunning type_of_running = TypeOfRunning::kNone;
constexpr static double kMaxTime = 10.0;
};
template <typename InType, typename OutType>
class Perf {
public:
// Init performance analysis with an initialized task and initialized data
explicit Perf(const ppc::task::TaskPtr<InType, OutType> &task_ptr) : task_(task_ptr) {
task_ptr->GetStateOfTesting() = ppc::task::StateOfTesting::kPerf;
}
// Check performance of full task's pipeline: PreProcessing() ->
// Validation() -> Run() -> PostProcessing()
void PipelineRun(const PerfAttr &perf_attr) {
perf_results_.type_of_running = PerfResults::TypeOfRunning::kPipeline;
CommonRun(perf_attr, [&] {
task_->Validation();
task_->PreProcessing();
task_->Run();
task_->PostProcessing();
}, perf_results_);
}
// Check performance of task's Run() function
void TaskRun(const PerfAttr &perf_attr) {
perf_results_.type_of_running = PerfResults::TypeOfRunning::kTaskRun;
task_->Validation();
task_->PreProcessing();
CommonRun(perf_attr, [&] { task_->Run(); }, perf_results_);
task_->PostProcessing();
task_->Validation();
task_->PreProcessing();
task_->Run();
task_->PostProcessing();
}
// Print results for automation checkers
void PrintPerfStatistic(const std::string &test_id) const {
std::string type_test_name;
if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kTaskRun) {
type_test_name = "task_run";
} else if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kPipeline) {
type_test_name = "pipeline";
} else {
std::stringstream err_msg;
err_msg << '\n' << "The type of performance check for the task was not selected.\n";
throw std::runtime_error(err_msg.str().c_str());
}
auto time_secs = perf_results_.time_sec;
const auto max_time = ppc::util::GetPerfMaxTime();
std::stringstream perf_res_str;
if (time_secs < max_time) {
perf_res_str << std::fixed << std::setprecision(10) << time_secs;
std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n';
} else {
std::stringstream err_msg;
err_msg << '\n' << "Task execute time need to be: ";
err_msg << "time < " << max_time << " secs." << '\n';
err_msg << "Original time in secs: " << time_secs << '\n';
perf_res_str << std::fixed << std::setprecision(10) << -1.0;
std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n';
throw std::runtime_error(err_msg.str().c_str());
}
}
/// @brief Retrieves the performance test results.
/// @return The latest PerfResults structure.
[[nodiscard]] PerfResults GetPerfResults() const {
return perf_results_;
}
private:
PerfResults perf_results_;
std::shared_ptr<ppc::task::Task<InType, OutType>> task_;
static void CommonRun(const PerfAttr &perf_attr, const std::function<void()> &pipeline, PerfResults &perf_results) {
auto begin = perf_attr.current_timer();
for (uint64_t i = 0; i < perf_attr.num_running; i++) {
pipeline();
}
auto end = perf_attr.current_timer();
perf_results.time_sec = (end - begin) / static_cast<double>(perf_attr.num_running);
}
};
inline std::string GetStringParamName(PerfResults::TypeOfRunning type_of_running) {
if (type_of_running == PerfResults::TypeOfRunning::kTaskRun) {
return "task_run";
}
if (type_of_running == PerfResults::TypeOfRunning::kPipeline) {
return "pipeline";
}
return "none";
}
} // namespace ppc::performance