Skip to content

Commit 764d64a

Browse files
committed
PWR080: Add benchmark
1 parent 27074b9 commit 764d64a

6 files changed

Lines changed: 171 additions & 0 deletions

File tree

Benchmark/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ if (OCB_Fortran_COMPILER_ID STREQUAL "GNU")
1919
add_benchmark(PWR075)
2020
endif()
2121
add_benchmark(PWR079)
22+
add_benchmark(PWR080)

Benchmark/src/PWR080.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include "Benchmark.h"
2+
3+
// Forward-declare the functions to benchmark
4+
extern "C" {
5+
double transform_and_sum(const int n, const double *array, const int option);
6+
double transform_and_sum_improved(const int n, const double *array,
7+
const int option);
8+
double transform_and_sum_f(const int n, const double *array, const int option);
9+
double transform_and_sum_improved_f(const int n, const double *array,
10+
const int option);
11+
}
12+
13+
// Size adjusted to fit execution on micro-seconds
14+
constexpr int N = 1024 * 1024;
15+
16+
#if OCB_ENABLE_C
17+
18+
static void CExampleBench(benchmark::State &state) {
19+
auto array = OpenCatalog::CreateRandomVector<double>(N);
20+
21+
for (auto _ : state) {
22+
double result = transform_and_sum(N, array.data(), /*option=*/-1);
23+
benchmark::DoNotOptimize(result);
24+
}
25+
}
26+
27+
static void CImprovedBench(benchmark::State &state) {
28+
auto array = OpenCatalog::CreateRandomVector<double>(N);
29+
30+
for (auto _ : state) {
31+
double result = transform_and_sum_improved(N, array.data(), /*option=*/-1);
32+
benchmark::DoNotOptimize(result);
33+
}
34+
}
35+
36+
// The goal of these benchmarks is to demonstrate that the suggested check does
37+
// not incur any performance penalty
38+
OC_BENCHMARK("PWR080 C Example", CExampleBench);
39+
OC_BENCHMARK("PWR080 C Improved", CImprovedBench);
40+
41+
#endif
42+
43+
#if OCB_ENABLE_Fortran
44+
45+
static void FortranExampleBench(benchmark::State &state) {
46+
auto array = OpenCatalog::CreateRandomVector<double>(N);
47+
48+
for (auto _ : state) {
49+
double result = transform_and_sum_f(N, array.data(), /*option=*/-1);
50+
benchmark::DoNotOptimize(result);
51+
}
52+
}
53+
54+
static void FortranImprovedBench(benchmark::State &state) {
55+
auto array = OpenCatalog::CreateRandomVector<double>(N);
56+
57+
for (auto _ : state) {
58+
double result =
59+
transform_and_sum_improved_f(N, array.data(), /*option=*/-1);
60+
benchmark::DoNotOptimize(result);
61+
}
62+
}
63+
64+
// The goal of these benchmarks is to demonstrate that the suggested check does
65+
// not incur any performance penalty
66+
OC_BENCHMARK("PWR080 Fortran Example", FortranExampleBench);
67+
OC_BENCHMARK("PWR080 Fortran Improved", FortranImprovedBench);
68+
69+
#endif

Checks/PWR080/benchmark/example.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// PWR080: Conditionally initialized variables can lead to undefined behavior
2+
3+
__attribute__((pure)) double transform_and_sum(const int n, const double *array,
4+
const int option) {
5+
double sum = 0.0;
6+
7+
double factor;
8+
if (option == 1) {
9+
factor = 0.5;
10+
} else if (option == 2) {
11+
factor = 2.0;
12+
}
13+
14+
for (int i = 0; i < n; ++i) {
15+
sum += array[i] * factor;
16+
}
17+
18+
return sum;
19+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
! PWR080: Conditionally initialized variables can lead to undefined behavior
2+
3+
! NOT-PWR070: Explicit-shape arrays used for C-interoperability
4+
pure function transform_and_sum_f(n, array, option) bind(c)
5+
use iso_c_binding, only: c_double, c_int
6+
implicit none
7+
8+
integer(kind=c_int), intent(in), value :: n
9+
real(kind=c_double), dimension(n), intent(in) :: array
10+
integer(kind=c_int), intent(in), value :: option
11+
real(kind=c_double) :: transform_and_sum_f
12+
13+
real(kind=c_double) :: sum
14+
real(kind=c_double) :: factor
15+
integer(kind=c_int) :: i
16+
17+
sum = 0.0
18+
19+
if (option == 1) then
20+
factor = 0.5
21+
else if (option == 2) then
22+
factor = 2.0
23+
end if
24+
25+
do i = 1, n
26+
sum = sum + array(i) * factor
27+
end do
28+
29+
transform_and_sum_f = sum
30+
end function transform_and_sum_f

Checks/PWR080/benchmark/solution.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// PWR080: Conditionally initialized variables can lead to undefined behavior
2+
3+
__attribute__((pure)) double
4+
transform_and_sum_improved(const int n, const double *array, const int option) {
5+
double sum = 0.0;
6+
7+
// Identity transformation by default
8+
double factor = 1.0;
9+
if (option == 1) {
10+
factor = 0.5;
11+
} else if (option == 2) {
12+
factor = 2.0;
13+
}
14+
15+
for (int i = 0; i < n; ++i) {
16+
sum += array[i] * factor;
17+
}
18+
19+
return sum;
20+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
! PWR080: Conditionally initialized variables can lead to undefined behavior
2+
3+
! NOT-PWR070: Explicit-shape arrays used for C-interoperability
4+
pure function transform_and_sum_improved_f(n, array, option) bind(c)
5+
use iso_c_binding, only: c_double, c_int
6+
implicit none
7+
8+
integer(kind=c_int), intent(in), value :: n
9+
real(kind=c_double), dimension(n), intent(in) :: array
10+
integer(kind=c_int), intent(in), value :: option
11+
real(kind=c_double) :: transform_and_sum_improved_f
12+
13+
real(kind=c_double) :: sum
14+
real(kind=c_double) :: factor
15+
integer(kind=c_int) :: i
16+
17+
sum = 0.0
18+
! Identity transformation by default
19+
factor = 1.0
20+
21+
if (option == 1) then
22+
factor = 0.5
23+
else if (option == 2) then
24+
factor = 2.0
25+
end if
26+
27+
do i = 1, n
28+
sum = sum + array(i) * factor
29+
end do
30+
31+
transform_and_sum_improved_f = sum
32+
end function transform_and_sum_improved_f

0 commit comments

Comments
 (0)