C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
exprtk_rtc_overhead.cpp
Go to the documentation of this file.
1/*
2 **************************************************************
3 * C++ Mathematical Expression Toolkit Library *
4 * *
5 * ExprTk Vector RTC Overhead Analysis *
6 * Author: Arash Partow (1999-2024) *
7 * URL: https://www.partow.net/programming/exprtk/index.html *
8 * *
9 * Copyright notice: *
10 * Free use of the Mathematical Expression Toolkit Library is *
11 * permitted under the guidelines and in accordance with the *
12 * most current version of the MIT License. *
13 * https://www.opensource.org/licenses/MIT *
14 * SPDX-License-Identifier: MIT *
15 * *
16 **************************************************************
17*/
18
19
20#include <cstdio>
21#include <string>
22
23#include "exprtk.hpp"
24
25
27{
29 {
30 throw std::runtime_error("Runtime vector access violation.");
31 return false;
32 }
33};
34
35struct assert_handler final : public exprtk::assert_check
36{
37 void handle_assert(const assert_context& /*context*/) override
38 {
39 throw std::runtime_error("assert: vector access violation.");
40 }
41};
42
43template <typename T>
45{
46 typedef exprtk::expression<T> expression_t;
47 typedef exprtk::parser<T> parser_t;
48
49 const std::string sieve_of_eratosthenes_program =
50 " var sieve[10^8] := [false]; "
51 " var m := trunc(sqrt(sieve[])); "
52 " "
53 " sieve[0] := true; "
54 " sieve[1] := true; "
55 " "
56 " for (var i := 0; i <= m; i += 1) "
57 " { "
58 " assert(i < sieve[]); "
59 " if (false == sieve[i]) "
60 " { "
61 " for (var j := i^2; j < sieve[]; j += i) "
62 " { "
63 " assert(j < sieve[]); "
64 " sieve[j] := true; "
65 " } "
66 " } "
67 " }; "
68 " "
69 " var prime_count := sieve[] - sum(sieve); "
70 " "
71 " prime_count == 5761455; ";
72
73 T nortc_result = T(0);
74 T rtc_result = T(0);
75 T assert_result = T(0);
76
77 T nortc_time_sec = T(0);
78 T rtc_time_sec = T(0);
79 T assert_time_sec = T(0);
80
81 {
82 expression_t expression;
83
84 parser_t parser;
85 parser.compile(sieve_of_eratosthenes_program,expression);
86
87 exprtk::timer timer;
88 timer.start();
89
90 nortc_result = expression.value();
91
92 timer.stop();
93 nortc_time_sec = timer.time();
94 }
95
96 {
97 vector_access_rtc vec_rtc;
98
99 expression_t expression;
100
101 parser_t parser;
102 parser.register_vector_access_runtime_check(vec_rtc);
103 parser.compile(sieve_of_eratosthenes_program,expression);
104
105 exprtk::timer timer;
106 timer.start();
107
108 rtc_result = expression.value();
109
110 timer.stop();
111 rtc_time_sec = timer.time();
112 }
113
114 {
115 assert_handler asrt_handler;
116 expression_t expression;
117
118 parser_t parser;
119 parser.register_assert_check(asrt_handler);
120 parser.compile(sieve_of_eratosthenes_program,expression);
121
122 exprtk::timer timer;
123 timer.start();
124
125 assert_result = expression.value();
126
127 timer.stop();
128 assert_time_sec = timer.time();
129 }
130
131 if (
132 (nortc_result == T(1) ) &&
133 (nortc_result == rtc_result ) &&
134 (nortc_result == assert_result)
135 )
136 {
137 printf("Prime Sieve - NORTC time: %5.3fsec\tRTC time: %5.3fsec\tassert time: %5.3fsec\trtc_overhead: %5.3f%%\tassert_overhead: %5.3f%%\n",
138 nortc_time_sec,
139 rtc_time_sec,
140 assert_time_sec,
141 std::max(0.0, 100.0 * ((rtc_time_sec - nortc_time_sec) / nortc_time_sec)),
142 std::max(0.0, 100.0 * ((assert_time_sec - nortc_time_sec) / nortc_time_sec)));
143 }
144 else
145 printf("ERROR - Results of NORTC and RTC runs do not match!\n");
146}
147
148template <typename T>
150{
151 typedef exprtk::symbol_table<T> symbol_table_t;
152 typedef exprtk::expression<T> expression_t;
153 typedef exprtk::parser<T> parser_t;
154
155 const std::string bubble_sort_program =
156 " var upper_bound := v[]; "
157 " "
158 " repeat "
159 " var new_upper_bound := 0; "
160 " "
161 " for (var i := 1; i < upper_bound; i += 1) "
162 " { "
163 " assert(i < v[]); "
164 " if (v[i - 1] > v[i]) "
165 " { "
166 " v[i - 1] <=> v[i]; "
167 " new_upper_bound := i; "
168 " }; "
169 " }; "
170 " "
171 " upper_bound := new_upper_bound; "
172 " "
173 " until (upper_bound <= 1); "
174 " "
175 " var result := true; "
176 " "
177 " for (var i := 1; i < v[]; i += 1) "
178 " { "
179 " assert(i < v[]); "
180 " if (v[i - 1] > v[i]) "
181 " { "
182 " result := false; "
183 " }; "
184 " }; "
185 " "
186 " result; ";
187
188 T nortc_result = T(0);
189 T rtc_result = T(0);
190 T assert_result = T(0);
191
192 T nortc_time_sec = T(0);
193 T rtc_time_sec = T(0);
194 T assert_time_sec = T(0);
195
196 const std::size_t num_values = 10000;
197 std::vector<T> values(num_values, 0.0);
198
199 for (std::size_t i = 0; i < values.size(); ++i)
200 {
201 values[i] = static_cast<double>(values.size() - i);
202 }
203
204 {
205 std::vector<T> v = values;
206
207 symbol_table_t symbol_table;
208 symbol_table.add_vector("v", v);
209
210 expression_t expression;
211 expression.register_symbol_table(symbol_table);
212
213 parser_t parser;
214 parser.compile(bubble_sort_program, expression);
215
216 exprtk::timer timer;
217 timer.start();
218
219 nortc_result = expression.value();
220
221 timer.stop();
222 nortc_time_sec = timer.time();
223 }
224
225 {
226 std::vector<T> v = values;
227
228 symbol_table_t symbol_table;
229 symbol_table.add_vector("v", v);
230
231 vector_access_rtc vec_rtc;
232
233 expression_t expression;
234 expression.register_symbol_table(symbol_table);
235
236 parser_t parser;
237 parser.register_vector_access_runtime_check(vec_rtc);
238 parser.compile(bubble_sort_program, expression);
239
240 exprtk::timer timer;
241 timer.start();
242
243 rtc_result = expression.value();
244
245 timer.stop();
246 rtc_time_sec = timer.time();
247 }
248
249 {
250 std::vector<T> v = values;
251
252 symbol_table_t symbol_table;
253 symbol_table.add_vector("v", v);
254
255 expression_t expression;
256 expression.register_symbol_table(symbol_table);
257
258 assert_handler asrt_handler;
259
260 parser_t parser;
261 parser.register_assert_check(asrt_handler);
262 parser.compile(bubble_sort_program, expression);
263
264 exprtk::timer timer;
265 timer.start();
266
267 assert_result = expression.value();
268
269 timer.stop();
270 assert_time_sec = timer.time();
271 }
272
273 if (
274 (nortc_result == T(1) ) &&
275 (nortc_result == rtc_result ) &&
276 (nortc_result == assert_result)
277 )
278 {
279 printf("Bubble Sort - NORTC time: %5.3fsec\tRTC time: %5.3fsec\tassert time: %5.3fsec\trtc_overhead: %5.3f%%\tassert_overhead: %5.3f%%\n",
280 nortc_time_sec,
281 rtc_time_sec,
282 assert_time_sec,
283 std::max(0.0, 100.0 * ((rtc_time_sec - nortc_time_sec) / nortc_time_sec)),
284 std::max(0.0, 100.0 * ((assert_time_sec - nortc_time_sec) / nortc_time_sec)));
285 }
286 else
287 printf("ERROR - Results of NORTC and RTC runs do not match!\n");
288}
289
290int main(int argc, char* argv[])
291{
292 const std::size_t rounds = ((argc == 2) ? atoi(argv[1]) : 5);
293
294 for (std::size_t i = 0; i < rounds; ++i)
295 {
296 vector_rtc_overhead_analysis_01<double>();
297 }
298
299 printf("-------------------------\n");
300
301 for (std::size_t i = 0; i < rounds; ++i)
302 {
303 vector_rtc_overhead_analysis_02<double>();
304 }
305
306 return 0;
307}
double time() const
Definition exprtk.hpp:43502
static const std::size_t rounds
void vector_rtc_overhead_analysis_02()
void vector_rtc_overhead_analysis_01()
void handle_assert(const assert_context &) override
bool handle_runtime_violation(violation_context &) override