Skip to content

Commit bfdced4

Browse files
authored
Merge pull request #643 from ckormanyos/syntax_and_bench
Improve syntax and math benchmark
2 parents 16c357a + a12e37d commit bfdced4

File tree

15 files changed

+156
-130
lines changed

15 files changed

+156
-130
lines changed

.github/workflows/real-time-cpp-benchmarks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ jobs:
172172
- name: benchmark_single-stm32f446
173173
run: |
174174
mkdir -p bin
175-
arm-none-eabi-g++ -std=c++20 -Wall -Wextra -pedantic -O2 -g -gdwarf-2 -ffunction-sections -fdata-sections -x c++ -fno-rtti -fno-use-cxa-atexit -fno-exceptions -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs -ftemplate-depth=32 -mcpu=cortex-m4 -mtune=cortex-m4 -mthumb -mfloat-abi=soft -mno-unaligned-access -mno-long-calls -I./src/mcal/stm32f446 -I./src -DAPP_BENCHMARK_TYPE=APP_BENCHMARK_TYPE_CRC -DAPP_BENCHMARK_STANDALONE_MAIN ./src/app/benchmark/app_benchmark_crc.cpp ./target/micros/stm32f446/make/single/crt.cpp -nostartfiles -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_crc.map -T ./target/micros/stm32f446/make/stm32f446.ld -o ./bin/app_benchmark_crc.elf
175+
arm-none-eabi-g++ -std=c++20 -Wall -Wextra -Wpedantic -O2 -g -gdwarf-2 -ffunction-sections -fdata-sections -x c++ -fno-rtti -fno-use-cxa-atexit -fno-exceptions -fno-nonansi-builtins -fno-threadsafe-statics -fno-enforce-eh-specs -ftemplate-depth=32 -mcpu=cortex-m4 -mtune=cortex-m4 -mthumb -mfloat-abi=soft -mno-unaligned-access -mno-long-calls -I./src/mcal/stm32f446 -I./src -DAPP_BENCHMARK_TYPE=APP_BENCHMARK_TYPE_CRC -DAPP_BENCHMARK_STANDALONE_MAIN ./src/app/benchmark/app_benchmark_crc.cpp ./target/micros/stm32f446/make/single/crt.cpp -nostartfiles -Wl,--gc-sections -Wl,-Map,./bin/app_benchmark_crc.map -T ./target/micros/stm32f446/make/stm32f446.ld -o ./bin/app_benchmark_crc.elf
176176
arm-none-eabi-objcopy ./bin/app_benchmark_crc.elf -O ihex ./bin/app_benchmark_crc.hex
177177
ls -la ./bin/app_benchmark_crc.elf ./bin/app_benchmark_crc.hex ./bin/app_benchmark_crc.map
178178
working-directory: ./ref_app/

ref_app/cmake/gcc-toolchain.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
##############################################################################
2-
# Copyright Christopher Kormanyos 2021.
2+
# Copyright Christopher Kormanyos 2021 - 2025.
33
# Distributed under the Boost Software License,
44
# Version 1.0. (See accompanying file LICENSE_1_0.txt
55
# or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -94,7 +94,7 @@ set(GCCFLAGS
9494
-g
9595
-Wall
9696
-Wextra
97-
-pedantic
97+
-Wpedantic
9898
-Wmain
9999
-Wundef
100100
-Wsign-conversion

ref_app/src/app/benchmark/app_benchmark_trapezoid_integral.cpp

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
///////////////////////////////////////////////////////////////////////////////
2-
// Copyright Christopher Kormanyos 2021 - 2024.
2+
// Copyright Christopher Kormanyos 2021 - 2025.
33
// Distributed under the Boost Software License,
44
// Version 1.0. (See accompanying file LICENSE_1_0.txt
55
// or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -31,17 +31,17 @@
3131
#if (defined(STDFLOAT_FLOAT64_NATIVE_TYPE) || (defined(__STDCPP_FLOAT64_T__) && (__STDCPP_FLOAT64_T__ == 1)))
3232

3333
using local_float_type = std::float64_t;
34-
static_assert((std::numeric_limits<local_float_type>::digits >= 53), "Error: Incorrect my_float_type type definition");
34+
static_assert((std::numeric_limits<local_float_type>::digits >= 53), "Error: Incorrect local_float_type type definition");
3535

3636
#elif (defined(STDFLOAT_FLOAT32_NATIVE_TYPE) || (defined(__STDCPP_FLOAT32_T__) && (__STDCPP_FLOAT32_T__ == 1)))
3737

3838
using local_float_type = std::float32_t;
39-
static_assert((std::numeric_limits<local_float_type>::digits >= 24), "Error: Incorrect my_float_type type definition");
39+
static_assert((std::numeric_limits<local_float_type>::digits >= 24), "Error: Incorrect local_float_type type definition");
4040

4141
#else
4242

4343
using local_float_type = double;
44-
static_assert((std::numeric_limits<local_float_type>::digits >= 53), "Error: Incorrect my_float_type type definition");
44+
static_assert((std::numeric_limits<local_float_type>::digits >= 53), "Error: Incorrect local_float_type type definition");
4545

4646
#endif
4747

@@ -56,50 +56,55 @@ using my_float_type = ::local_float_type;
5656
#include <math/calculus/integral.h>
5757
#include <math/constants/constants.h>
5858

59-
namespace
59+
namespace local
6060
{
6161
template<typename FloatingPointType>
6262
auto cyl_bessel_j(const std::uint_fast8_t n, const FloatingPointType& x) -> FloatingPointType
6363
{
6464
using local_float_type = FloatingPointType;
6565

66-
constexpr auto epsilon = std::numeric_limits<local_float_type>::epsilon();
67-
6866
using std::sqrt;
6967

70-
const auto tol = sqrt(epsilon);
71-
72-
const auto integration_result =
73-
math::integral(static_cast<local_float_type>(0),
74-
math::constants::pi<local_float_type>(),
75-
tol,
76-
[&x, &n](const local_float_type& t) noexcept
77-
{
78-
using std::cos;
79-
using std::sin;
80-
81-
return
82-
static_cast<local_float_type>
83-
(
84-
cos(x * sin(t) - (t * static_cast<local_float_type>(n)))
85-
);
86-
});
68+
const local_float_type tol { sqrt(std::numeric_limits<local_float_type>::epsilon()) };
69+
70+
const local_float_type
71+
integration_result
72+
{
73+
math::integral
74+
(
75+
static_cast<local_float_type>(0),
76+
math::constants::pi<local_float_type>(),
77+
tol,
78+
[&x, &n](const local_float_type& t) noexcept
79+
{
80+
using std::cos;
81+
using std::sin;
82+
83+
return cos(static_cast<local_float_type>((x * sin(t)) - (t * static_cast<local_float_type>(n))));
84+
}
85+
)
86+
};
8787

8888
return integration_result / math::constants::pi<local_float_type>();
8989
}
90-
}
90+
} // namespace local
9191

9292
auto app::benchmark::run_trapezoid_integral() -> bool
9393
{
94-
constexpr auto app_benchmark_tolerance =
95-
static_cast<my_float_type>
96-
(
94+
constexpr my_float_type
95+
app_benchmark_tolerance
96+
{
9797
std::numeric_limits<my_float_type>::epsilon() * static_cast<my_float_type>(100.0L)
98-
);
98+
};
9999

100-
// Compute y = cyl_bessel_j(2, 1.23) = 0.16636938378681407351267852431513159437103348245333
100+
// Test the value of a Bessel function.
101+
// Here is a control value from Wolfram Alpha.
101102
// N[BesselJ[2, 123/100], 50]
102-
const auto j2 = cyl_bessel_j(static_cast<std::uint_fast8_t>(UINT8_C(2)), static_cast<my_float_type>(1.23L));
103+
// 0.16636938378681407351267852431513159437103348245333
104+
105+
// Compute cyl_bessel_j(2, 1.23)
106+
107+
const my_float_type j2 { local::cyl_bessel_j(std::uint_fast8_t { UINT8_C(2) }, static_cast<my_float_type>(1.23L)) };
103108

104109
const bool app_benchmark_result_is_ok =
105110
detail::is_close_fraction

ref_app/src/math/calculus/integral.h

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,68 @@
11
///////////////////////////////////////////////////////////////////////////////
2-
// Copyright Christopher Kormanyos 2007 - 2021.
2+
// Copyright Christopher Kormanyos 2007 - 2025.
33
// Distributed under the Boost Software License,
44
// Version 1.0. (See accompanying file LICENSE_1_0.txt
55
// or copy at http://www.boost.org/LICENSE_1_0.txt)
66
//
77

8-
#ifndef INTEGRAL_2012_01_09_H_
9-
#define INTEGRAL_2012_01_09_H_
8+
#ifndef INTEGRAL_2012_01_09_H
9+
#define INTEGRAL_2012_01_09_H
1010

11-
#include <cmath>
11+
#include <cmath>
1212

13-
namespace math
14-
{
15-
template<typename real_value_type,
16-
typename real_function_type>
17-
real_value_type integral(const real_value_type& a,
18-
const real_value_type& b,
19-
const real_value_type& tol,
20-
real_function_type real_function)
21-
{
22-
std::uint_fast32_t n2(1);
13+
namespace math
14+
{
15+
// Compute the numerical integral of a real function from a to b
16+
// using a recursive trapezoid rule.
2317

24-
real_value_type step = ((b - a) / 2U);
18+
template<typename real_value_type,
19+
typename real_function_type>
20+
real_value_type integral(const real_value_type& a,
21+
const real_value_type& b,
22+
const real_value_type& tol,
23+
real_function_type real_function)
24+
{
25+
std::uint_fast32_t n2 { UINT8_C(1) };
2526

26-
real_value_type result = (real_function(a) + real_function(b)) * step;
27+
real_value_type step { (b - a) / 2U };
2728

28-
const std::uint_fast8_t k_max = UINT8_C(32);
29+
real_value_type result { (real_function(a) + real_function(b)) * step };
2930

30-
for(std::uint_fast8_t k = UINT8_C(0); k < k_max; ++k)
31-
{
32-
real_value_type sum(0);
31+
constexpr std::uint_fast8_t k_max { UINT8_C(32) };
3332

34-
for(std::uint_fast32_t j(0U); j < n2; ++j)
35-
{
36-
const std::uint_fast32_t two_j_plus_one = (j * UINT32_C(2)) + UINT32_C(1);
33+
for(std::uint_fast8_t k = UINT8_C(0); k < k_max; ++k)
34+
{
35+
real_value_type sum { 0 };
3736

38-
sum += real_function(a + real_value_type(step * real_value_type(two_j_plus_one)));
39-
}
37+
for(std::uint_fast32_t j { std::uint_fast32_t { UINT8_C(0) } }; j < n2; ++j)
38+
{
39+
const std::uint_fast32_t two_j_plus_one { (j * UINT32_C(2)) + UINT32_C(1) };
4040

41-
const real_value_type tmp = result;
41+
sum += real_function(a + real_value_type(step * two_j_plus_one));
42+
}
4243

43-
result = (result / 2U) + (step * sum);
44+
const real_value_type tmp { result };
4445

45-
using std::fabs;
46+
result = (result / 2U) + (step * sum);
4647

47-
const real_value_type ratio = fabs(tmp / result);
48+
const real_value_type ratio { tmp / result };
4849

49-
const real_value_type delta = fabs(ratio - 1U);
50+
using std::fabs;
5051

51-
if((k > UINT8_C(1)) && (delta < tol))
52-
{
53-
break;
54-
}
52+
const real_value_type delta = fabs(ratio - 1U);
5553

56-
n2 *= 2U;
54+
if((k > std::uint_fast8_t { UINT8_C(1) }) && (delta < tol))
55+
{
56+
break;
57+
}
5758

58-
step /= 2U;
59-
}
59+
n2 *= 2U;
6060

61-
return result;
62-
}
63-
}
61+
step /= 2U;
62+
}
6463

65-
#endif // INTEGRAL_2012_01_09_H_
64+
return result;
65+
}
66+
}
67+
68+
#endif // INTEGRAL_2012_01_09_H

ref_app/src/mcal/mcal_gcc_cxx_completion.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ extern "C"
8989
// and objects.
9090

9191
void abort () __attribute__((noreturn));
92-
int atexit (void (*)()) noexcept;
92+
int atexit (void (*)());
9393
int at_quick_exit (void (*)());
9494
void _Exit (int) __attribute__((noreturn));
9595
void exit (int) __attribute__((noreturn));
@@ -111,7 +111,7 @@ extern "C"
111111
// Implementations of patched functions.
112112

113113
void abort () { for(;;) { mcal::cpu::nop(); } }
114-
int atexit (void (*)()) noexcept { return 0; }
114+
int atexit (void (*)()) { return 0; }
115115
int at_quick_exit (void (*)()) { return 0; }
116116
void _Exit (int) { for(;;) { mcal::cpu::nop(); } }
117117
void exit (int) { for(;;) { mcal::cpu::nop(); } }

ref_app/src/sys/start/sys_start.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#if (defined(__XTENSA__) && !defined(CONFIG_IDF_TARGET_ESP32S3))
1818
extern "C" ATTRIBUTE(used) auto app_main_loop() -> int;
1919
#else
20-
extern "C" ATTRIBUTE(used) auto main() -> int;
20+
ATTRIBUTE(used) auto main() -> int;
2121
#endif
2222

2323
#if (defined(__XTENSA__) && !defined(CONFIG_IDF_TARGET_ESP32S3))
@@ -29,7 +29,7 @@ auto main() -> int
2929
// Initialize the microcontroller abstraction layer.
3030
mcal::init();
3131

32-
// Start the multitasking scheduler. (This does not return.)
32+
// Start the multitasking scheduler. This does not return.
3333
// Handle an unexpected return from main() in the startup code.
3434
os::start_os();
3535

ref_app/src/util/STL/cmath

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,25 @@
4141
#define NAN (-(float)(INFINITY * 0.0F))
4242
#endif
4343

44-
#define _DENORM (-2)
45-
#define _FINITE (-1)
46-
#define _INFCODE 1
47-
#define _NANCODE 2
48-
49-
#define FP_INFINITE _INFCODE
50-
#define FP_NAN _NANCODE
51-
#define FP_NORMAL _FINITE
52-
#define FP_SUBNORMAL _DENORM
53-
#define FP_ZERO 0
44+
#if !defined(FP_NAN)
45+
#define FP_NAN 0
46+
#endif
47+
#if !defined(FP_INFINITE)
48+
#define FP_INFINITE 1
49+
#endif
50+
#if !defined(FP_ZERO)
51+
#define FP_ZERO 2
52+
#endif
53+
#if !defined(FP_SUBNORMAL)
54+
#define FP_SUBNORMAL 3
55+
#endif
56+
#if !defined(FP_NORMAL)
57+
#define FP_NORMAL 4
58+
#endif
5459

55-
#define _C2 1 // 0 if not 2's complement
56-
#define FP_ILOGB0 (-0x7fffffff - _C2)
57-
#define FP_ILOGBNAN 0x7fffffff
60+
#define _C2 1L // 0 if not 2's complement
61+
#define FP_ILOGB0 (-0x7fffffffL - _C2)
62+
#define FP_ILOGBNAN 0x7fffffffL
5863

5964
static_assert((__SIZEOF_LONG_DOUBLE__ > 0) && (__SIZEOF_LONG_DOUBLE__ >= __SIZEOF_DOUBLE__),
6065
"Error: Configuration error regarding 64-bit double/long-double for AVR");
@@ -249,6 +254,9 @@
249254

250255
namespace std
251256
{
257+
using float_t = float;
258+
using double_t = double;
259+
252260
inline bool isnan (float x) { return (__BUILTIN_ISNANF(x) == 1); }
253261
inline bool isnan (double x) { return (__BUILTIN_ISNAN (x) == 1); }
254262
inline bool isnan (long double x) { return (__BUILTIN_ISNANL(x) == 1); }
@@ -688,24 +696,27 @@
688696
}
689697
#endif
690698

691-
#if !defined(FP_INFINITE)
692-
#define FP_INFINITE 1
693-
#endif
694699
#if !defined(FP_NAN)
695-
#define FP_NAN 2
700+
#define FP_NAN 0
696701
#endif
697-
#if !defined(FP_NORMAL)
698-
#define FP_NORMAL (-1)
702+
#if !defined(FP_INFINITE)
703+
#define FP_INFINITE 1
704+
#endif
705+
#if !defined(FP_ZERO)
706+
#define FP_ZERO 2
699707
#endif
700708
#if !defined(FP_SUBNORMAL)
701-
#define FP_SUBNORMAL (-2)
709+
#define FP_SUBNORMAL 3
702710
#endif
703-
#if !defined(FP_ZERO)
704-
#define FP_ZERO 0
711+
#if !defined(FP_NORMAL)
712+
#define FP_NORMAL 4
705713
#endif
706714

707715
namespace std
708716
{
717+
using float_t = float;
718+
using double_t = double;
719+
709720
using ::isfinite;
710721
using ::ilogb;
711722

ref_app/src/util/STL/stdfloat

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
///////////////////////////////////////////////////////////////////////////////
2-
// Copyright Christopher Kormanyos 2007 - 2024.
2+
// Copyright Christopher Kormanyos 2007 - 2025.
33
// Distributed under the Boost Software License,
44
// Version 1.0. (See accompanying file LICENSE_1_0.txt
55
// or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -12,6 +12,8 @@
1212
#pragma GCC system_header
1313
#endif
1414

15+
#include <limits>
16+
1517
namespace std
1618
{
1719
using float32_t = float;
@@ -32,4 +34,7 @@
3234
#endif
3335
}
3436

37+
static_assert((std::numeric_limits<std::float32_t>::digits == 24), "Error: Incorrect float32_t type definition");
38+
static_assert((std::numeric_limits<std::float64_t>::digits == 53), "Error: Incorrect float64_t type definition");
39+
3540
#endif // STDFLOAT_2024_07_12

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy