Skip to content

Commit d0b45e8

Browse files
committed
Add microprofile integration for performance profiling
Introduce microprofile for detailed performance profiling and reporting. Replace CSV-based performance tables with HTML reports, generated and published under `docs/scoreboard/profiles`. Update build system, scripts, and CI workflows to support profiling and automate report publishing.
1 parent 7bbec06 commit d0b45e8

11 files changed

Lines changed: 122 additions & 19 deletions

File tree

.github/workflows/perf.yml

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ jobs:
3030
PPC_NUM_THREADS: 2
3131
OMPI_ALLOW_RUN_AS_ROOT: 1
3232
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1
33-
- name: Archive results
34-
working-directory: build
35-
run: zip -r ../perf-stat.zip perf_stat_dir
36-
- name: Upload results
37-
uses: actions/upload-artifact@v4
38-
with:
39-
name: perf-stat
40-
path: perf-stat.zip
33+
- name: Build scoreboard index
34+
run: python3 scripts/scoreboard_index.py
35+
- name: Publish profiles
36+
run: |
37+
git config user.email "ci@users.noreply.github.com"
38+
git config user.name "CI"
39+
git add docs/scoreboard
40+
git commit -m "Update microprofile reports [ci]" || echo "No changes"
41+
git push
4142
macos-clang-build-perf-stats:
4243
runs-on: macOS-latest
4344
steps:
@@ -66,11 +67,12 @@ jobs:
6667
env:
6768
PPC_NUM_PROC: 1
6869
PPC_NUM_THREADS: 2
69-
- name: Archive results
70-
working-directory: build
71-
run: zip -r perf-stat-macos.zip perf_stat_dir
72-
- name: Upload results
73-
uses: actions/upload-artifact@v4
74-
with:
75-
name: perf-stat-macos
76-
path: perf-stat-macos.zip
70+
- name: Build scoreboard index
71+
run: python3 scripts/scoreboard_index.py
72+
- name: Publish profiles
73+
run: |
74+
git config user.email "ci@users.noreply.github.com"
75+
git config user.name "CI"
76+
git add docs/scoreboard
77+
git commit -m "Update microprofile reports [ci]" || echo "No changes"
78+
git push

.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/microprofile"]
17+
path = 3rdparty/microprofile
18+
url = https://github.com/jonasmr/microprofile

3rdparty/microprofile

Submodule microprofile added at 88e8f4b

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ endif()
66

77
message( STATUS "Parallel Programming Course (PPC)" )
88
project(parallel_programming_course)
9+
option(PPC_ENABLE_PROFILING "Enable microprofile instrumentation (perf tests only)" ON)
910

1011
############################ Scoreboard #############################
1112

@@ -29,6 +30,7 @@ message( STATUS "PPC step: First configures" )
2930
include(cmake/configure.cmake)
3031
include(cmake/modes.cmake)
3132
include(cmake/sanitizers.cmake)
33+
include(cmake/ppc_profiler.cmake)
3234
foreach(dep json libenvpp stb)
3335
include(cmake/${dep}.cmake)
3436
endforeach()

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ For more detailed documentation and resources, please visit documentation pages:
1212

1313
Course scoreboard is available [here](https://learning-process.github.io/parallel_programming_course/scoreboard/).
1414

15+
Note: performance CSV tables are deprecated. Microprofile HTML reports are published under `docs/scoreboard/profiles/*.html` with an index at `docs/scoreboard/README.md`.
16+
1517
Coverage report is available [here](https://learning-process.github.io/parallel_programming_course/coverage/).
1618

1719
### Parallel programming technologies:

cmake/ppc_profiler.cmake

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
if(PPC_ENABLE_PROFILING)
2+
add_library(ppc_microprofile STATIC
3+
3rdparty/microprofile/microprofile.cpp
4+
)
5+
target_include_directories(ppc_microprofile PUBLIC
6+
${CMAKE_SOURCE_DIR}/3rdparty/microprofile
7+
${CMAKE_SOURCE_DIR}/modules/common/include
8+
)
9+
target_compile_definitions(ppc_microprofile PUBLIC
10+
MICROPROFILE_ENABLED=1
11+
MICROPROFILE_USE_CONFIG=1
12+
)
13+
else()
14+
add_library(ppc_microprofile INTERFACE)
15+
target_compile_definitions(ppc_microprofile INTERFACE MICROPROFILE_ENABLED=0)
16+
endif()
17+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
#define MICROPROFILE_WEBSERVER 0
3+
#define MICROPROFILE_MINIZ 0
4+
#define MICROPROFILE_PER_THREAD_BUFFER_SIZE (1024*1024)
5+

modules/util/include/perf_test_util.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#include "task/include/task.hpp"
1919
#include "util/include/util.hpp"
2020

21+
#if MICROPROFILE_ENABLED
22+
#include "microprofile.h"
23+
#endif
24+
2125
namespace ppc::util {
2226

2327
double GetTimeMPI();
@@ -46,6 +50,11 @@ class BaseRunPerfTests : public ::testing::TestWithParam<PerfTestParam<InType, O
4650
virtual InType GetTestInputData() = 0;
4751

4852
virtual void SetPerfAttributes(ppc::performance::PerfAttr& perf_attrs) {
53+
#if MICROPROFILE_ENABLED
54+
(void)perf_attrs;
55+
// Timing is handled by microprofile in perf tests.
56+
return;
57+
#else
4958
if (task_->GetDynamicTypeOfTask() == ppc::task::TypeOfTask::kMPI ||
5059
task_->GetDynamicTypeOfTask() == ppc::task::TypeOfTask::kALL) {
5160
const double t0 = GetTimeMPI();
@@ -65,6 +74,7 @@ class BaseRunPerfTests : public ::testing::TestWithParam<PerfTestParam<InType, O
6574
} else {
6675
throw std::runtime_error("The task type is not supported for performance testing.");
6776
}
77+
#endif
6878
}
6979

7080
void ExecuteTest(const PerfTestParam<InType, OutType>& perf_test_param) {
@@ -83,18 +93,42 @@ class BaseRunPerfTests : public ::testing::TestWithParam<PerfTestParam<InType, O
8393
SetPerfAttributes(perf_attr);
8494

8595
if (mode == ppc::performance::PerfResults::TypeOfRunning::kPipeline) {
96+
#if MICROPROFILE_ENABLED
97+
{
98+
MICROPROFILE_SCOPEI("perf", test_name.c_str(), MP_GREEN);
99+
perf.PipelineRun(perf_attr);
100+
}
101+
#else
86102
perf.PipelineRun(perf_attr);
103+
#endif
87104
} else if (mode == ppc::performance::PerfResults::TypeOfRunning::kTaskRun) {
105+
#if MICROPROFILE_ENABLED
106+
{
107+
MICROPROFILE_SCOPEI("perf", test_name.c_str(), MP_GREEN);
108+
perf.TaskRun(perf_attr);
109+
}
110+
#else
88111
perf.TaskRun(perf_attr);
112+
#endif
89113
} else {
90114
std::stringstream err_msg;
91115
err_msg << '\n' << "The type of performance check for the task was not selected.\n";
92116
throw std::runtime_error(err_msg.str().c_str());
93117
}
94118

119+
#if MICROPROFILE_ENABLED
120+
if (GetMPIRank() == 0) {
121+
const char* out_dir = std::getenv("PPC_PROFILE_OUT");
122+
if (!out_dir) out_dir = "docs/scoreboard/profiles";
123+
const std::string capture = test_name + ".html";
124+
const std::string out = std::string(out_dir) + "/" + capture;
125+
MicroProfileDumpFileImmediately(out.c_str(), capture.c_str(), -1);
126+
}
127+
#else
95128
if (GetMPIRank() == 0) {
96129
perf.PrintPerfStatistic(test_name);
97130
}
131+
#endif
98132

99133
OutType output_data = task_->GetOutput();
100134
ASSERT_TRUE(CheckTestOutputData(output_data));

scripts/generate_perf_results.sh

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
mkdir -p build/perf_stat_dir
5-
scripts/run_tests.py --running-type="performance" | tee build/perf_stat_dir/perf_log.txt
6-
python3 scripts/create_perf_table.py --input build/perf_stat_dir/perf_log.txt --output build/perf_stat_dir
4+
OUT_DIR="docs/scoreboard/profiles"
5+
mkdir -p "${OUT_DIR}"
6+
7+
export PPC_PROFILE_OUT="${OUT_DIR}"
8+
9+
# Preserve the same perf binary runs as before
10+
scripts/run_tests.py --running-type="performance"
11+
12+
echo "Perf runs completed. HTML profiles are in ${OUT_DIR}"

scripts/scoreboard_index.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/usr/bin/env python3
2+
import pathlib, datetime
3+
4+
PROFILES = pathlib.Path("docs/scoreboard/profiles")
5+
OUT_MD = pathlib.Path("docs/scoreboard/README.md")
6+
7+
def main():
8+
PROFILES.mkdir(parents=True, exist_ok=True)
9+
OUT_MD.parent.mkdir(parents=True, exist_ok=True)
10+
items = sorted(p for p in PROFILES.glob("*.html"))
11+
lines = [
12+
"# Scoreboard\n",
13+
"_Профили выполнений (microprofile). Таблица производительности отключена._\n\n",
14+
f"Generated: {datetime.datetime.utcnow().isoformat()}Z\n\n",
15+
]
16+
if not items:
17+
lines.append("> Profiles not found.\n")
18+
else:
19+
lines.append("## Profiles\n\n")
20+
for p in items:
21+
lines.append(f"- [{p.name}]({p.name})\n")
22+
OUT_MD.write_text("".join(lines), encoding="utf-8")
23+
24+
if __name__ == "__main__":
25+
main()
26+

0 commit comments

Comments
 (0)