Skip to content

Commit dcb0687

Browse files
committed
enhance performance module: improve code documentation, refactor performance measurement logic, and add utility for result string conversion
1 parent ab3303f commit dcb0687

File tree

1 file changed

+147
-62
lines changed

1 file changed

+147
-62
lines changed

modules/performance/include/performance.hpp

Lines changed: 147 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -11,112 +11,197 @@
1111

1212
#include "task/include/task.hpp"
1313

14+
using namespace ppc::task;
15+
1416
namespace ppc::performance {
1517

18+
/**
19+
* @brief Default timer function used for performance measurement.
20+
* @return A fake time value (-1.0).
21+
*/
1622
inline double DefaultTimer() { return -1.0; }
1723

24+
/**
25+
* @brief Attributes used to configure performance measurement.
26+
*/
1827
struct PerfAttr {
19-
/// @brief Number of times the task is run for performance evaluation.
28+
/**
29+
* @brief Number of repetitions of the task for averaging performance.
30+
*/
2031
uint64_t num_running = 5;
21-
/// @brief Timer function returning current time in seconds.
22-
/// @cond
32+
33+
/**
34+
* @brief Timer function returning current time in seconds.
35+
* Default is a fake function returning -1.0.
36+
*/
2337
std::function<double()> current_timer = DefaultTimer;
24-
/// @endcond
2538
};
2639

40+
/**
41+
* @brief Stores the results of a performance test.
42+
*/
2743
struct PerfResults {
28-
/// @brief Measured execution time in seconds.
44+
/**
45+
* @brief Measured execution time in seconds (average over runs).
46+
*/
2947
double time_sec = 0.0;
30-
enum TypeOfRunning : uint8_t { kPipeline, kTaskRun, kNone } type_of_running = kNone;
48+
49+
/**
50+
* @brief Type of performance test performed.
51+
*/
52+
enum TypeOfRunning : uint8_t {
53+
kPipeline, ///< Full pipeline: Validation → PreProcessing → Run → PostProcessing
54+
kTaskRun, ///< Only Run() function is measured
55+
kNone ///< No performance test was executed
56+
} type_of_running = kNone;
57+
58+
/**
59+
* @brief Maximum allowed execution time in seconds.
60+
*/
3161
constexpr static double kMaxTime = 10.0;
3262
};
3363

64+
/**
65+
* @brief Converts a TypeOfRunning enum value to its string representation.
66+
* @param type_of_running Enum value indicating which performance type was run.
67+
* @return String name corresponding to the enum.
68+
*/
69+
inline std::string GetStringParamName(PerfResults::TypeOfRunning type_of_running) {
70+
switch (type_of_running) {
71+
case PerfResults::kTaskRun:
72+
return "task_run";
73+
case PerfResults::kPipeline:
74+
return "pipeline";
75+
default:
76+
return "none";
77+
}
78+
}
79+
80+
/**
81+
* @brief Measures performance of a given task using configured attributes.
82+
* @tparam InType Input type of the task.
83+
* @tparam OutType Output type of the task.
84+
*/
3485
template <typename InType, typename OutType>
3586
class Perf {
3687
public:
37-
// Init performance analysis with an initialized task and initialized data
38-
explicit Perf(const ppc::task::TaskPtr<InType, OutType>& task_ptr) : task_(task_ptr) {
39-
task_ptr->GetStateOfTesting() = ppc::task::StateOfTesting::kPerf;
88+
/**
89+
* @brief Constructs a performance tester for the given task.
90+
* @param task_ptr Shared pointer to a task object.
91+
*/
92+
explicit Perf(const ::TaskPtr<InType, OutType>& task_ptr) : task_(task_ptr) {
93+
task_ptr->GetStateOfTesting() = ::StateOfTesting::kPerf;
4094
}
41-
// Check performance of full task's pipeline: PreProcessing() ->
42-
// Validation() -> Run() -> PostProcessing()
95+
96+
/**
97+
* @brief Runs the full task pipeline and measures its performance.
98+
* The full pipeline includes: Validation → PreProcessing → Run → PostProcessing.
99+
* @param perf_attr Performance measurement configuration.
100+
*/
43101
void PipelineRun(const PerfAttr& perf_attr) {
44-
perf_results_.type_of_running = PerfResults::TypeOfRunning::kPipeline;
45-
46-
CommonRun(perf_attr, [&] {
47-
task_->Validation();
48-
task_->PreProcessing();
49-
task_->Run();
50-
task_->PostProcessing();
51-
}, perf_results_);
102+
perf_results_.type_of_running = PerfResults::kPipeline;
103+
CommonRun(perf_attr, RunFullPipeline<::Task<InType, OutType>>);
52104
}
53-
// Check performance of task's Run() function
105+
106+
/**
107+
* @brief Measures only the Run() part of the task.
108+
* Pre/Post-processing and validation are still invoked before and after.
109+
* @param perf_attr Performance measurement configuration.
110+
*/
54111
void TaskRun(const PerfAttr& perf_attr) {
55-
perf_results_.type_of_running = PerfResults::TypeOfRunning::kTaskRun;
112+
perf_results_.type_of_running = PerfResults::kTaskRun;
56113

57114
task_->Validation();
58115
task_->PreProcessing();
59-
CommonRun(perf_attr, [&] { task_->Run(); }, perf_results_);
116+
CommonRun(perf_attr, RunOnly<::Task<InType, OutType>>);
60117
task_->PostProcessing();
61118

119+
// Ensure correctness after performance run
62120
task_->Validation();
63121
task_->PreProcessing();
64122
task_->Run();
65123
task_->PostProcessing();
66124
}
67-
// Pint results for automation checkers
125+
126+
/**
127+
* @brief Prints formatted performance results or throws if too slow.
128+
* Prints output in format: test_id:type:time_in_seconds
129+
* @param test_id Identifier for the current test (e.g., "omp_4_threads").
130+
* @throws std::runtime_error if execution time exceeds allowed maximum.
131+
*/
68132
void PrintPerfStatistic(const std::string& test_id) const {
69-
std::string type_test_name;
70-
if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kTaskRun) {
71-
type_test_name = "task_run";
72-
} else if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kPipeline) {
73-
type_test_name = "pipeline";
74-
} else {
75-
std::stringstream err_msg;
76-
err_msg << '\n' << "The type of performance check for the task was not selected.\n";
77-
throw std::runtime_error(err_msg.str().c_str());
133+
const auto& type = perf_results_.type_of_running;
134+
const std::string type_name = GetStringParamName(type);
135+
136+
if (type == PerfResults::kNone) {
137+
throw std::runtime_error("The type of performance check for the task was not selected.\n");
78138
}
79139

80-
auto time_secs = perf_results_.time_sec;
81-
std::stringstream perf_res_str;
140+
std::stringstream ss;
141+
double time_secs = perf_results_.time_sec;
142+
82143
if (time_secs < PerfResults::kMaxTime) {
83-
perf_res_str << std::fixed << std::setprecision(10) << time_secs;
84-
std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n';
144+
ss << std::fixed << std::setprecision(10) << time_secs;
85145
} else {
86-
std::stringstream err_msg;
87-
err_msg << '\n' << "Task execute time need to be: ";
88-
err_msg << "time < " << PerfResults::kMaxTime << " secs." << '\n';
89-
err_msg << "Original time in secs: " << time_secs << '\n';
90-
perf_res_str << std::fixed << std::setprecision(10) << -1.0;
91-
std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n';
92-
throw std::runtime_error(err_msg.str().c_str());
146+
ss << std::fixed << std::setprecision(10) << -1.0;
147+
std::stringstream err;
148+
err << "Task execute time need to be: time < " << PerfResults::kMaxTime
149+
<< " secs.\nOriginal time in secs: " << time_secs << '\n';
150+
std::cout << test_id << ":" << type_name << ":" << ss.str() << '\n';
151+
throw std::runtime_error(err.str());
93152
}
153+
154+
std::cout << test_id << ":" << type_name << ":" << ss.str() << '\n';
94155
}
95-
/// @brief Retrieves the performance test results.
96-
/// @return The latest PerfResults structure.
156+
157+
/**
158+
* @brief Retrieves performance test results.
159+
* @return Struct containing latest performance data.
160+
*/
97161
[[nodiscard]] PerfResults GetPerfResults() const { return perf_results_; }
98162

99163
private:
100-
PerfResults perf_results_;
101-
std::shared_ptr<ppc::task::Task<InType, OutType>> task_;
102-
static void CommonRun(const PerfAttr& perf_attr, const std::function<void()>& pipeline, PerfResults& perf_results) {
103-
auto begin = perf_attr.current_timer();
104-
for (uint64_t i = 0; i < perf_attr.num_running; i++) {
105-
pipeline();
106-
}
107-
auto end = perf_attr.current_timer();
108-
perf_results.time_sec = (end - begin) / static_cast<double>(perf_attr.num_running);
164+
PerfResults perf_results_; ///< Stores measurement results and mode.
165+
std::shared_ptr<::Task<InType, OutType>> task_; ///< Pointer to task being tested.
166+
167+
/**
168+
* @brief Executes the full pipeline for the given task.
169+
* @tparam TaskType Type of the task.
170+
* @param task Shared pointer to the task instance.
171+
*/
172+
template <typename TaskType>
173+
static void RunFullPipeline(const std::shared_ptr<TaskType>& task) {
174+
task->Validation();
175+
task->PreProcessing();
176+
task->Run();
177+
task->PostProcessing();
109178
}
110-
};
111179

112-
inline std::string GetStringParamName(PerfResults::TypeOfRunning type_of_running) {
113-
if (type_of_running == PerfResults::kTaskRun) {
114-
return "task_run";
180+
/**
181+
* @brief Executes only the Run() method of the given task.
182+
* @tparam TaskType Type of the task.
183+
* @param task Shared pointer to the task instance.
184+
*/
185+
template <typename TaskType>
186+
static void RunOnly(const std::shared_ptr<TaskType>& task) {
187+
task->Run();
115188
}
116-
if (type_of_running == PerfResults::kPipeline) {
117-
return "pipeline";
189+
190+
/**
191+
* @brief Measures execution time of a given function over multiple runs.
192+
* @tparam Func Type of callable taking shared_ptr to task.
193+
* @param perf_attr Attributes controlling the number of runs and timer.
194+
* @param func Callable that invokes the desired part of the task.
195+
*/
196+
template <typename Func>
197+
void CommonRun(const PerfAttr& perf_attr, Func func) {
198+
double begin = perf_attr.current_timer();
199+
for (uint64_t i = 0; i < perf_attr.num_running; ++i) {
200+
func(task_);
201+
}
202+
double end = perf_attr.current_timer();
203+
perf_results_.time_sec = (end - begin) / static_cast<double>(perf_attr.num_running);
118204
}
119-
return "none";
120-
}
205+
};
121206

122207
} // namespace ppc::performance

0 commit comments

Comments
 (0)