Skip to content

Commit f67cba4

Browse files
committed
Use Google Benchmark for performance tables
1 parent c358e80 commit f67cba4

26 files changed

Lines changed: 780 additions & 917 deletions

File tree

.github/workflows/perf.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
tar -xzvf ubuntu-gcc-install-ubuntu-24.04.tar.gz -C install
3131
- name: Run perf tests
3232
run: |
33-
bash -e scripts/generate_perf_results.sh
33+
scripts/run_tests.py --running-type=performance
3434
env:
3535
PPC_NUM_PROC: 2
3636
PPC_NUM_THREADS: 2
@@ -68,7 +68,7 @@ jobs:
6868
tar -xzvf macos-clang-install.tar.gz -C install
6969
- name: Run perf tests
7070
run: |
71-
bash -e scripts/generate_perf_results.sh
71+
scripts/run_tests.py --running-type=performance
7272
env:
7373
PPC_NUM_PROC: 1
7474
PPC_NUM_THREADS: 2

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@
1313
[submodule "3rdparty/libenvpp"]
1414
path = 3rdparty/libenvpp
1515
url = https://github.com/ph3at/libenvpp
16+
[submodule "3rdparty/benchmark"]
17+
path = 3rdparty/benchmark
18+
url = https://github.com/google/benchmark

3rdparty/benchmark

Submodule benchmark added at a846068

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ endforeach()
4444

4545
message( STATUS "PPC step: Setup external projects" )
4646
include(cmake/gtest.cmake)
47+
include(cmake/benchmark.cmake)
4748

4849
############################## Modules ##############################
4950

cmake/benchmark.cmake

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
include_guard()
2+
3+
include(ExternalProject)
4+
5+
ExternalProject_Add(
6+
ppc_benchmark
7+
SOURCE_DIR "${CMAKE_SOURCE_DIR}/3rdparty/benchmark"
8+
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark"
9+
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/build"
10+
INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/install"
11+
EXCLUDE_FROM_ALL TRUE
12+
CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
13+
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
14+
-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}
15+
-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}
16+
-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
17+
-DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED}
18+
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
19+
${PPC_EXTERNAL_PROJECT_CMAKE_ARGS}
20+
-DCMAKE_C_FLAGS=-w
21+
-DCMAKE_CXX_FLAGS=-w
22+
-DBENCHMARK_ENABLE_TESTING=OFF
23+
-DBENCHMARK_ENABLE_GTEST_TESTS=OFF
24+
-DBENCHMARK_ENABLE_WERROR=OFF
25+
-DBENCHMARK_ENABLE_INSTALL=ON
26+
-DBENCHMARK_ENABLE_LIBPFM=OFF
27+
BUILD_COMMAND
28+
"${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/build"
29+
--config $<CONFIG> --parallel
30+
INSTALL_COMMAND
31+
"${CMAKE_COMMAND}" --install
32+
"${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/build" --config $<CONFIG>
33+
--prefix "${CMAKE_CURRENT_BINARY_DIR}/ppc_benchmark/install"
34+
${PPC_EXTERNAL_PROJECT_LOG_ARGS})
35+
36+
function(ppc_include_benchmark target_name)
37+
target_include_directories(
38+
${target_name} PUBLIC ${CMAKE_SOURCE_DIR}/3rdparty/benchmark/include)
39+
target_compile_definitions(${target_name} PUBLIC BENCHMARK_STATIC_DEFINE)
40+
endfunction()
41+
42+
function(ppc_link_benchmark target_name)
43+
ppc_include_benchmark(${target_name})
44+
add_dependencies(${target_name} ppc_benchmark)
45+
target_link_directories(${target_name} PUBLIC
46+
"${CMAKE_BINARY_DIR}/ppc_benchmark/install/lib")
47+
target_link_libraries(${target_name} PUBLIC benchmark Threads::Threads)
48+
if(WIN32)
49+
target_link_libraries(${target_name} PUBLIC shlwapi)
50+
endif()
51+
endfunction()

modules/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ set_target_properties(${exec_func_lib} PROPERTIES LINKER_LANGUAGE CXX)
2626
target_include_directories(
2727
${exec_func_lib} PUBLIC ${CMAKE_SOURCE_DIR}/3rdparty
2828
${CMAKE_SOURCE_DIR}/modules ${CMAKE_SOURCE_DIR}/tasks)
29+
ppc_include_benchmark(${exec_func_lib})
2930

3031
foreach(
3132
link

modules/performance/include/performance.hpp

Lines changed: 9 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <iomanip>
66
#include <iostream>
77
#include <memory>
8-
#include <sstream>
98
#include <stdexcept>
109
#include <string>
1110

@@ -30,12 +29,7 @@ struct PerfAttr {
3029
struct PerfResults {
3130
/// @brief Measured execution time in seconds.
3231
double time_sec = 0.0;
33-
enum class TypeOfRunning : uint8_t {
34-
kPipeline,
35-
kTaskRun,
36-
kNone,
37-
};
38-
TypeOfRunning type_of_running = TypeOfRunning::kNone;
32+
bool is_measured = false;
3933
constexpr static double kMaxTime = 10.0;
4034
};
4135

@@ -46,22 +40,8 @@ class Perf {
4640
explicit Perf(const ppc::task::TaskPtr<InType, OutType> &task_ptr) : task_(task_ptr) {
4741
task_ptr->GetStateOfTesting() = ppc::task::StateOfTesting::kPerf;
4842
}
49-
// Check performance of full task's pipeline: PreProcessing() ->
50-
// Validation() -> Run() -> PostProcessing()
51-
void PipelineRun(const PerfAttr &perf_attr) {
52-
perf_results_.type_of_running = PerfResults::TypeOfRunning::kPipeline;
53-
54-
CommonRun(perf_attr, [&] {
55-
task_->Validation();
56-
task_->PreProcessing();
57-
task_->Run();
58-
task_->PostProcessing();
59-
}, perf_results_);
60-
}
6143
// Check performance of task's Run() function
6244
void TaskRun(const PerfAttr &perf_attr) {
63-
perf_results_.type_of_running = PerfResults::TypeOfRunning::kTaskRun;
64-
6545
task_->Validation();
6646
task_->PreProcessing();
6747
CommonRun(perf_attr, [&] { task_->Run(); }, perf_results_);
@@ -74,31 +54,17 @@ class Perf {
7454
}
7555
// Print results for automation checkers
7656
void PrintPerfStatistic(const std::string &test_id) const {
77-
std::string type_test_name;
78-
if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kTaskRun) {
79-
type_test_name = "task_run";
80-
} else if (perf_results_.type_of_running == PerfResults::TypeOfRunning::kPipeline) {
81-
type_test_name = "pipeline";
82-
} else {
83-
std::stringstream err_msg;
84-
err_msg << '\n' << "The type of performance check for the task was not selected.\n";
85-
throw std::runtime_error(err_msg.str().c_str());
57+
if (!perf_results_.is_measured) {
58+
throw std::runtime_error("Performance measurement was not run.");
8659
}
8760

8861
auto time_secs = perf_results_.time_sec;
8962
const auto max_time = ppc::util::GetPerfMaxTime();
90-
std::stringstream perf_res_str;
9163
if (time_secs < max_time) {
92-
perf_res_str << std::fixed << std::setprecision(10) << time_secs;
93-
std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n';
64+
std::cout << test_id << ':' << std::fixed << std::setprecision(10) << time_secs << '\n';
9465
} else {
95-
std::stringstream err_msg;
96-
err_msg << '\n' << "Task execute time need to be: ";
97-
err_msg << "time < " << max_time << " secs." << '\n';
98-
err_msg << "Original time in secs: " << time_secs << '\n';
99-
perf_res_str << std::fixed << std::setprecision(10) << -1.0;
100-
std::cout << test_id << ":" << type_test_name << ":" << perf_res_str.str() << '\n';
101-
throw std::runtime_error(err_msg.str().c_str());
66+
std::cout << test_id << ':' << std::fixed << std::setprecision(10) << -1.0 << '\n';
67+
throw std::runtime_error("Task execution time exceeded the performance limit.");
10268
}
10369
}
10470
/// @brief Retrieves the performance test results.
@@ -110,24 +76,15 @@ class Perf {
11076
private:
11177
PerfResults perf_results_;
11278
std::shared_ptr<ppc::task::Task<InType, OutType>> task_;
113-
static void CommonRun(const PerfAttr &perf_attr, const std::function<void()> &pipeline, PerfResults &perf_results) {
79+
static void CommonRun(const PerfAttr &perf_attr, const std::function<void()> &operation, PerfResults &perf_results) {
11480
auto begin = perf_attr.current_timer();
11581
for (uint64_t i = 0; i < perf_attr.num_running; i++) {
116-
pipeline();
82+
operation();
11783
}
11884
auto end = perf_attr.current_timer();
11985
perf_results.time_sec = (end - begin) / static_cast<double>(perf_attr.num_running);
86+
perf_results.is_measured = true;
12087
}
12188
};
12289

123-
inline std::string GetStringParamName(PerfResults::TypeOfRunning type_of_running) {
124-
if (type_of_running == PerfResults::TypeOfRunning::kTaskRun) {
125-
return "task_run";
126-
}
127-
if (type_of_running == PerfResults::TypeOfRunning::kPipeline) {
128-
return "pipeline";
129-
}
130-
return "none";
131-
}
132-
13390
} // namespace ppc::performance

modules/performance/tests/perf_tests.cpp

Lines changed: 14 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include <gtest/gtest.h>
22

3-
#include <array>
43
#include <chrono>
54
#include <cstdint>
65
#include <filesystem>
@@ -68,37 +67,37 @@ class FakePerfTask : public TestPerfTask<InType, OutType> {
6867

6968
namespace ppc::performance {
7069

71-
TEST(PerfTests, CheckPerfPipeline) {
70+
TEST(PerfTests, CheckPerfTaskRun) {
7271
std::vector<uint32_t> in(2000, 1);
7372

7473
auto test_task = std::make_shared<ppc::test::TestPerfTask<std::vector<uint32_t>, uint32_t>>(in);
7574

7675
Perf<std::vector<uint32_t>, uint32_t> perf_analyzer(test_task);
7776

7877
PerfAttr perf_attr;
79-
perf_analyzer.PipelineRun(perf_attr);
78+
perf_analyzer.TaskRun(perf_attr);
8079

81-
perf_analyzer.PrintPerfStatistic("check_perf_pipeline");
80+
perf_analyzer.PrintPerfStatistic("check_perf");
8281
ASSERT_LE(perf_analyzer.GetPerfResults().time_sec, PerfResults::kMaxTime);
8382
EXPECT_EQ(test_task->GetOutput(), in.size());
8483
}
8584

86-
TEST(PerfTests, CheckPerfPipelineFloat) {
85+
TEST(PerfTests, CheckPerfTaskRunFloat) {
8786
std::vector<float> in(2000, 1);
8887

8988
auto test_task = std::make_shared<ppc::test::TestPerfTask<std::vector<float>, float>>(in);
9089

9190
Perf<std::vector<float>, float> perf_analyzer(test_task);
9291

9392
PerfAttr perf_attr;
94-
perf_analyzer.PipelineRun(perf_attr);
93+
perf_analyzer.TaskRun(perf_attr);
9594

96-
perf_analyzer.PrintPerfStatistic("check_perf_pipeline_float");
95+
perf_analyzer.PrintPerfStatistic("check_perf_float");
9796
ASSERT_LE(perf_analyzer.GetPerfResults().time_sec, PerfResults::kMaxTime);
9897
EXPECT_EQ(test_task->GetOutput(), in.size());
9998
}
10099

101-
TEST(PerfTests, CheckPerfPipelineUint8tSlowTest) {
100+
TEST(PerfTests, CheckPerfUint8tSlowTest) {
102101
std::vector<uint8_t> in(128, 1);
103102

104103
auto test_task = std::make_shared<ppc::test::FakePerfTask<std::vector<uint8_t>, uint8_t>>(in);
@@ -114,9 +113,9 @@ TEST(PerfTests, CheckPerfPipelineUint8tSlowTest) {
114113
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(current_time_point - t0).count();
115114
return static_cast<double>(duration) * 1e-9;
116115
};
117-
perf_analyzer.PipelineRun(perf_attr);
116+
perf_analyzer.TaskRun(perf_attr);
118117

119-
ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_pipeline_uint8_t_slow_test"));
118+
ASSERT_ANY_THROW(perf_analyzer.PrintPerfStatistic("check_perf_uint8_t_slow_test"));
120119
}
121120

122121
TEST(PerfTests, SlowPerfRespectsEnvOverride) {
@@ -132,7 +131,7 @@ TEST(PerfTests, SlowPerfRespectsEnvOverride) {
132131
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(current_time_point - t0).count();
133132
return static_cast<double>(duration) * 1e-9;
134133
};
135-
perf_analyzer.PipelineRun(perf_attr);
134+
perf_analyzer.TaskRun(perf_attr);
136135
EXPECT_NO_THROW(perf_analyzer.PrintPerfStatistic("slow_perf_respects_env_override"));
137136
}
138137

@@ -164,26 +163,6 @@ TEST(PerfTests, CheckPerfTaskFloat) {
164163
EXPECT_EQ(test_task->GetOutput(), in.size());
165164
}
166165

167-
struct ParamTestCase {
168-
PerfResults::TypeOfRunning input;
169-
std::string_view expected_output;
170-
};
171-
172-
namespace {
173-
174-
constexpr std::array<ParamTestCase, 3> kParamTestCases = {
175-
{{.input = PerfResults::TypeOfRunning::kTaskRun, .expected_output = "task_run"},
176-
{.input = PerfResults::TypeOfRunning::kPipeline, .expected_output = "pipeline"},
177-
{.input = PerfResults::TypeOfRunning::kNone, .expected_output = "none"}}};
178-
179-
} // namespace
180-
181-
TEST(GetStringParamNameParamTest, ReturnsExpectedString) {
182-
for (const auto &param : kParamTestCases) {
183-
EXPECT_EQ(GetStringParamName(param.input), std::string(param.expected_output));
184-
}
185-
}
186-
187166
struct TaskTypeTestCase {
188167
TypeOfTask type;
189168
std::string_view expected;
@@ -336,7 +315,7 @@ TEST(GetNamespaceTest, ReturnsEmptyStringForGlobalNamespaceType) {
336315
EXPECT_EQ(ppc::util::GetNamespace<int>(), "");
337316
}
338317

339-
TEST(PerfTest, PipelineRunAndTaskRun) {
318+
TEST(PerfTest, TaskRunMeasuresExecutionTime) {
340319
auto task_ptr = std::make_shared<DummyTask>();
341320
Perf<int, int> perf(task_ptr);
342321

@@ -349,15 +328,10 @@ TEST(PerfTest, PipelineRunAndTaskRun) {
349328
return t;
350329
};
351330

352-
EXPECT_NO_THROW(perf.PipelineRun(attr));
353-
auto res_pipeline = perf.GetPerfResults();
354-
EXPECT_EQ(res_pipeline.type_of_running, PerfResults::TypeOfRunning::kPipeline);
355-
EXPECT_GT(res_pipeline.time_sec, 0.0);
356-
357331
EXPECT_NO_THROW(perf.TaskRun(attr));
358-
auto res_taskrun = perf.GetPerfResults();
359-
EXPECT_EQ(res_taskrun.type_of_running, PerfResults::TypeOfRunning::kTaskRun);
360-
EXPECT_GT(res_taskrun.time_sec, 0.0);
332+
auto result = perf.GetPerfResults();
333+
EXPECT_TRUE(result.is_measured);
334+
EXPECT_GT(result.time_sec, 0.0);
361335
}
362336

363337
TEST(PerfTest, PrintPerfStatisticThrowsOnNone) {
@@ -370,12 +344,6 @@ TEST(PerfTest, PrintPerfStatisticThrowsOnNone) {
370344
ppc::util::DestructorFailureFlag::Unset();
371345
}
372346

373-
TEST(PerfTest, GetStringParamNameTest) {
374-
EXPECT_EQ(GetStringParamName(PerfResults::TypeOfRunning::kTaskRun), "task_run");
375-
EXPECT_EQ(GetStringParamName(PerfResults::TypeOfRunning::kPipeline), "pipeline");
376-
EXPECT_EQ(GetStringParamName(PerfResults::TypeOfRunning::kNone), "none");
377-
}
378-
379347
TEST(TaskTest, DestructorInvalidPipelineOrderTerminatesPartialPipeline) {
380348
{
381349
struct BadTask : Task<int, int> {

0 commit comments

Comments
 (0)