-
Notifications
You must be signed in to change notification settings - Fork 165
/
app_benchmark_pi_agm.cpp
155 lines (132 loc) · 6.67 KB
/
app_benchmark_pi_agm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2021 - 2024.
// Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <cmath>
#include <cstdint>
#include <app/benchmark/app_benchmark.h>
#if (defined(APP_BENCHMARK_TYPE) && ((APP_BENCHMARK_TYPE == APP_BENCHMARK_TYPE_PI_AGM) || (APP_BENCHMARK_TYPE == APP_BENCHMARK_TYPE_PI_AGM_100)))
#define WIDE_DECIMAL_DISABLE_IOSTREAM
#define WIDE_DECIMAL_DISABLE_DYNAMIC_MEMORY_ALLOCATION
#define WIDE_DECIMAL_DISABLE_CONSTRUCT_FROM_STRING
#define WIDE_DECIMAL_DISABLE_CACHED_CONSTANTS
#define WIDE_DECIMAL_DISABLE_USE_STD_FUNCTION
#define WIDE_DECIMAL_NAMESPACE ckormanyos
#include <math/wide_decimal/decwide_t.h>
#include <mcal_memory/mcal_memory_progmem_array.h>
#include <util/memory/util_n_slot_array_allocator.h>
// Define APP_BENCHMARK_TYPE_PI_AGM_USES_101_DIGITS in order
// to go up to 101 decimal digits in the pi AGM calculation.
// If this is done, however, the AVR target needs a bit more RAM,
// which can be subtracted from the ample stack in the LD file.
// When using 101 decmial digits on the AVR, also consider
// switching the optimization level to -O2 in order to speed
// up the calculation a bit.
// Benchmarks (with -O2) on AVR show about 200ms needed
// for 53 decimal digits, whereas about 480ms are needed
// for the 101 decimal digit calculation.
auto app::benchmark::run_pi_agm() -> bool
{
using local_limb_type = std::uint16_t;
#if (defined(APP_BENCHMARK_TYPE) && (APP_BENCHMARK_TYPE == APP_BENCHMARK_TYPE_PI_AGM_100))
constexpr auto wide_decimal_digits10 = static_cast<std::int32_t>(INT8_C(101));
#else
constexpr auto wide_decimal_digits10 = static_cast<std::int32_t>(INT8_C(53));
#endif
#if defined(WIDE_DECIMAL_NAMESPACE)
constexpr auto local_elem_number =
WIDE_DECIMAL_NAMESPACE::math::wide_decimal::detail::decwide_t_helper<wide_decimal_digits10, local_limb_type>::elem_number;
#else
constexpr auto local_elem_number =
math::wide_decimal::detail::decwide_t_helper<wide_decimal_digits10, local_limb_type>::elem_number;
#endif
using local_allocator_type = util::n_slot_array_allocator<void, local_elem_number, 18U>;
#if defined(WIDE_DECIMAL_NAMESPACE)
using local_wide_decimal_type = WIDE_DECIMAL_NAMESPACE::math::wide_decimal::decwide_t<wide_decimal_digits10,
local_limb_type,
local_allocator_type,
float,
std::int16_t,
float>;
#else
using local_wide_decimal_type = math::wide_decimal::decwide_t<wide_decimal_digits10,
local_limb_type,
local_allocator_type,
float,
std::int16_t,
float>;
#endif
// Use the Wolfram Alpha expression:
// N[Pi, 106] and truncate the final digit.
#if (defined(APP_BENCHMARK_TYPE) && (APP_BENCHMARK_TYPE == APP_BENCHMARK_TYPE_PI_AGM_100))
static const mcal::memory::progmem::array<typename local_wide_decimal_type::limb_type, 26U> app_benchmark_pi_agm_control MY_PROGMEM =
#else
static const mcal::memory::progmem::array<typename local_wide_decimal_type::limb_type, 14U> app_benchmark_pi_agm_control MY_PROGMEM =
#endif
{{
static_cast<local_limb_type>(UINT16_C( 3)),
static_cast<local_limb_type>(UINT16_C(1415)),
static_cast<local_limb_type>(UINT16_C(9265)),
static_cast<local_limb_type>(UINT16_C(3589)),
static_cast<local_limb_type>(UINT16_C(7932)),
static_cast<local_limb_type>(UINT16_C(3846)),
static_cast<local_limb_type>(UINT16_C(2643)),
static_cast<local_limb_type>(UINT16_C(3832)),
static_cast<local_limb_type>(UINT16_C(7950)),
static_cast<local_limb_type>(UINT16_C(2884)),
static_cast<local_limb_type>(UINT16_C(1971)),
static_cast<local_limb_type>(UINT16_C(6939)),
static_cast<local_limb_type>(UINT16_C(9375)),
static_cast<local_limb_type>(UINT16_C(1058)),
#if (defined(APP_BENCHMARK_TYPE) && (APP_BENCHMARK_TYPE == APP_BENCHMARK_TYPE_PI_AGM_100))
static_cast<local_limb_type>(UINT16_C(2097)),
static_cast<local_limb_type>(UINT16_C(4944)),
static_cast<local_limb_type>(UINT16_C(5923)),
static_cast<local_limb_type>(UINT16_C( 781)),
static_cast<local_limb_type>(UINT16_C(6406)),
static_cast<local_limb_type>(UINT16_C(2862)),
static_cast<local_limb_type>(UINT16_C( 899)),
static_cast<local_limb_type>(UINT16_C(8628)),
static_cast<local_limb_type>(UINT16_C( 348)),
static_cast<local_limb_type>(UINT16_C(2534)),
static_cast<local_limb_type>(UINT16_C(2117)),
static_cast<local_limb_type>(UINT16_C( 679))
#endif
}};
#if defined(WIDE_DECIMAL_NAMESPACE)
const local_wide_decimal_type my_pi =
WIDE_DECIMAL_NAMESPACE::math::wide_decimal::pi<wide_decimal_digits10,
local_limb_type,
local_allocator_type,
float,
std::int16_t,
float>();
#else
const local_wide_decimal_type my_pi =
math::wide_decimal::pi<wide_decimal_digits10,
local_limb_type,
local_allocator_type,
float,
std::int16_t,
float>();
#endif
const bool result_is_ok = std::equal(app_benchmark_pi_agm_control.cbegin(),
app_benchmark_pi_agm_control.cend(),
my_pi.crepresentation().cbegin());
return result_is_ok;
}
#if defined(APP_BENCHMARK_STANDALONE_MAIN)
int main()
{
// g++ -Wall -O3 -march=native -I./ref_app/src/mcal/host -I./ref_app/src -DAPP_BENCHMARK_TYPE=APP_BENCHMARK_TYPE_PI_AGM -DAPP_BENCHMARK_STANDALONE_MAIN ./ref_app/src/app/benchmark/app_benchmark_pi_agm.cpp -o ./ref_app/bin/app_benchmark_pi_agm.exe
bool result_is_ok = true;
for(unsigned i = 0U; i < 64U; ++i)
{
result_is_ok &= app::benchmark::run_pi_agm();
}
return result_is_ok ? 0 : -1;
}
#endif
#endif // APP_BENCHMARK_TYPE_PI_AGM