Skip to content

Commit

Permalink
PWR031: Add benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
inaki-amatria committed Dec 20, 2024
1 parent 3040d8a commit 907f9e8
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 0 deletions.
1 change: 1 addition & 0 deletions Benchmark/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_benchmark(PWR003)
add_benchmark(PWR022)
add_benchmark(PWR031)
add_benchmark(PWR032)
add_benchmark(PWR037)
add_benchmark(PWR039)
Expand Down
55 changes: 55 additions & 0 deletions Benchmark/src/PWR031.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "Benchmark.h"

// Forward-declare the functions to benchmark
extern "C" {
double midpoint_rule_x_pow_1_5_sin_x(double a, double b, int n);
double midpoint_rule_x_pow_1_5_sin_x_improved(double a, double b, int n);
double midpoint_rule_x_pow_1_5_sin_x_f(double a, double b, int n);
double midpoint_rule_x_pow_1_5_sin_x_improved_f(double a, double b, int n);
}

constexpr double a = 20.0;
constexpr double b = 30.0;
constexpr int n = 524288; // Adjusted size to fit on microseconds

#if OCB_ENABLE_C

static void CExampleBench(benchmark::State &state) {
for (auto _ : state) {
double result = midpoint_rule_x_pow_1_5_sin_x(a, b, n);
benchmark::DoNotOptimize(result);
}
}

static void CImprovedBench(benchmark::State &state) {
for (auto _ : state) {
double result = midpoint_rule_x_pow_1_5_sin_x_improved(a, b, n);
benchmark::DoNotOptimize(result);
}
}

OC_BENCHMARK("PWR031 C Example", CExampleBench);
OC_BENCHMARK("PWR031 C Improved", CImprovedBench);

#endif

#if OCB_ENABLE_Fortran

static void FortranExampleBench(benchmark::State &state) {
for (auto _ : state) {
double result = midpoint_rule_x_pow_1_5_sin_x_f(a, b, n);
benchmark::DoNotOptimize(result);
}
}

static void FortranImprovedBench(benchmark::State &state) {
for (auto _ : state) {
double result = midpoint_rule_x_pow_1_5_sin_x_improved_f(a, b, n);
benchmark::DoNotOptimize(result);
}
}

OC_BENCHMARK("PWR031 Fortran Example", FortranExampleBench);
OC_BENCHMARK("PWR031 Fortran Improved", FortranImprovedBench);

#endif
16 changes: 16 additions & 0 deletions Checks/PWR031/benchmark/example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// PWR031: Replace pow by multiplication, division and/or square root

#include <math.h>

// Computes the integral of $f(x) = x^{1.5} \sin(x)$ over the interval
// $\{a, b\}$ using the midpoint rule with $n$ samples
__attribute__((const)) double midpoint_rule_x_pow_1_5_sin_x(double a, double b,
int n) {
double integral = 0.0;
double dx = (b - a) / n;
for (int i = 0; i < n; ++i) {
double x = fma((i + 0.5), dx, a);
integral = fma(pow(x, 1.5) * sin(x), dx, integral);
}
return integral;
}
24 changes: 24 additions & 0 deletions Checks/PWR031/benchmark/example.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
! PWR031: Replace pow by multiplication, division and/or square root

! Computes the integral of $f(x) = x^{1.5} \sin(x)$ over the interval $\{a, b\}$
! using the midpoint rule with $n$ samples
pure function midpoint_rule_x_pow_1_5_sin_x_f(a, b, n) bind(c)
use iso_c_binding, only : c_double, c_int
implicit none
! function return type
real(kind=c_double) :: midpoint_rule_x_pow_1_5_sin_x_f
! dummy args
real(kind=c_double), intent(in), value :: a, b
integer(kind=c_int), intent(in), value :: n
! local vars
real(kind=c_double) :: integral, dx, x
integer(kind=c_int) :: i
!
integral = 0.0_c_double
dx = (b - a) / n
do i = 0_c_int, n
x = (real(i, kind=c_double) + 0.5_c_double) * dx + a
integral = integral + (x ** 1.5_c_double) * sin(x) * dx
end do
midpoint_rule_x_pow_1_5_sin_x_f = integral
end function midpoint_rule_x_pow_1_5_sin_x_f
16 changes: 16 additions & 0 deletions Checks/PWR031/benchmark/solution.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// PWR031: Replace pow by multiplication, division and/or square root

#include <math.h>

// Computes the integral of $f(x) = x^{1.5} \sin(x)$ over the interval
// $\{a, b\}$ using the midpoint rule with $n$ samples
__attribute__((const)) double
midpoint_rule_x_pow_1_5_sin_x_improved(double a, double b, int n) {
double integral = 0.0;
double dx = (b - a) / n;
for (int i = 0; i < n; ++i) {
double x = fma((i + 0.5), dx, a);
integral = fma(x * sqrt(x) * sin(x), dx, integral);
}
return integral;
}
24 changes: 24 additions & 0 deletions Checks/PWR031/benchmark/solution.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
! PWR031: Replace pow by multiplication, division and/or square root

! Computes the integral of $f(x) = x^{1.5} \sin(x)$ over the interval $\{a, b\}$
! using the midpoint rule with $n$ samples
pure function midpoint_rule_x_pow_1_5_sin_x_improved_f(a, b, n) bind(c)
use iso_c_binding, only : c_double, c_int
implicit none
! function return type
real(kind=c_double) :: midpoint_rule_x_pow_1_5_sin_x_improved_f
! dummy args
real(kind=c_double), intent(in), value :: a, b
integer(kind=c_int), intent(in), value :: n
! local vars
real(kind=c_double) :: integral, dx, x
integer(kind=c_int) :: i
!
integral = 0.0_c_double
dx = (b - a) / n
do i = 0_c_int, n
x = (real(i, kind=c_double) + 0.5_c_double) * dx + a
integral = integral + x * sqrt(x) * sin(x) * dx
end do
midpoint_rule_x_pow_1_5_sin_x_improved_f = integral
end function midpoint_rule_x_pow_1_5_sin_x_improved_f

0 comments on commit 907f9e8

Please sign in to comment.