C++ Mathematical Expression Toolkit (ExprTk) release
Loading...
Searching...
No Matches
exprtk_vector_benchmark_multithreaded.cpp
Go to the documentation of this file.
1/*
2 **************************************************************
3 * C++ Mathematical Expression Toolkit Library *
4 * *
5 * ExprTk Multi-Threaded Vector Processing Benchmark *
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 <fstream>
22#include <limits>
23#include <numeric>
24#include <string>
25#include <vector>
26#include <thread>
27
28#include "exprtk.hpp"
29
30
31struct test_expression
32{
33 std::size_t cost;
34 std::string expression;
35
36 test_expression(const std::size_t c, const std::string& ex)
37 : cost(c)
38 , expression(ex)
39 {}
40};
41
43 {
44 test_expression( 1, "2 * v0" ),
45 test_expression( 1, "v0 * 2" ),
46 test_expression( 2, "2v0 + 3" ),
47 test_expression( 2, "3 + 2v0" ),
48 test_expression( 5, "(2v0 + 3) * (2v0 + 3)" ),
49 test_expression( 5, "(3 + 2v0) * (3 + 2v0)" ),
50 test_expression( 1, "v0 + v1" ),
51 test_expression( 3, "(v0 + v1) * (v0 - v1)" ),
52 test_expression( 3, "2v0 + 3v1" ),
53 test_expression( 3, "2v0 - v1 / 3" ),
54 test_expression( 2, "v0 * v1 / v2" ),
55 test_expression( 3, "2(v0 * v1 / v2)" ),
56 test_expression( 4, "2(v0 / 3 + v1 / 4)" ),
57 test_expression( 3, "(2v0 - v1 / v2)" ),
58 test_expression( 4, "3(2v0 - v1 / v2)" ),
59 test_expression( 5, "7(5v0 * 3v1 / 2v2)" ),
60 test_expression( 5, "abs(v0 - v1) * abs(v1 - v0)" ),
61 test_expression( 7, "abs(2v0 - v1) * abs(v1 - 2v0)" ),
62 test_expression( 9, "abs(2v0 - 3v1) * abs(3v1 - 5v0)" ),
63 test_expression( 2, "sum(2 * v0)" ),
64 test_expression( 2, "sum(v0 * 2)" ),
65 test_expression( 2, "sum(v0 * v1)" ),
66 test_expression( 3, "sum(2v0 + 3)" ),
67 test_expression( 3, "sum(3 + 2v0)" ),
68 test_expression( 6, "sum((2v0 + 3) * (2v0 + 3))" ),
69 test_expression( 6, "sum((3 + 2v0) * (3 + 2v0))" ),
70 test_expression( 2, "sum(v0 + v1)" ),
71 test_expression( 4, "sum((v0 + v1) * (v0 - v1))" ),
72 test_expression( 4, "sum(2v0 + 3v1)" ),
73 test_expression( 4, "sum((2v0 - v1 / v2))" ),
74 test_expression( 5, "sum(3(2v0 - v1 / v2))" ),
75 test_expression( 4, "sum(abs(v0 * v1) / v2)" ),
76 test_expression( 5, "sum(v0 + v1) + avg(v0 - v1)" ),
77 test_expression( 8, "7(sum(abs(5v0 * 3v1) / 2v2))" ),
78 test_expression( 9, "sum(2v0 + 3v1) + sum(4 / v0 - 5 / v1)"),
79 test_expression( 6, "sum(abs(v0 - v1) * abs(v1 - v0))" ),
80 test_expression( 8, "sum(abs(2v0 - v1) * abs(v1 - 2v0))" ),
81 test_expression(10, "sum(abs(2v0 - 3v1) * abs(3v1 - 5v0))" ),
82 test_expression( 2, "axpbz(2,v0,3,v1)" ),
83 test_expression( 2, "axpy(2,v0,v1)" ),
84 //test_expression( 4, "sum(v0^2.2 + v1^3.3)" ),
85 //test_expression( 4, "exp(-1 / (v0^2))" ),
86 //test_expression( 5, "exp(-1 / (v0^2)) / v1" )
87 };
88
90
91const std::size_t rounds = 2000;
92
93typedef double numeric_type;
94
95template <typename T>
96void run_expression_benchmark(const std::size_t& vec_size,
97 const std::string& expression_string,
98 const std::size_t& cost)
99{
100 typedef exprtk::symbol_table<numeric_type> symbol_table_t;
101 typedef exprtk::expression<numeric_type> expression_t;
102 typedef exprtk::parser<numeric_type> parser_t;
103
104 std::vector<T> v0(vec_size, T(3.1234567890));
105 std::vector<T> v1(vec_size, T(5.1234567890));
106 std::vector<T> v2(vec_size, T(7.1234567890));
107
108 exprtk::rtl::vecops::package<T> vecops_package;
109
110 symbol_table_t symbol_table;
111 symbol_table.add_vector("v0",v0);
112 symbol_table.add_vector("v1",v1);
113 symbol_table.add_vector("v2",v2);
114 symbol_table.add_package(vecops_package);
115
116 expression_t expression;
117 expression.register_symbol_table(symbol_table);
118
119 parser_t parser;
120
121 if (!parser.compile(expression_string,expression))
122 {
123 printf("[load_expression] - Parser Error: %s\tExpression: %s\n",
124 parser.error().c_str(),
125 expression_string.c_str());
126
127 return;
128 }
129
130 exprtk::timer timer;
131
132 T total = T(0);
133
134 timer.start();
135
136 for (std::size_t r = 0; r < rounds; ++r)
137 {
138 total += expression.value();
139 }
140
141 timer.stop();
142
143 if (T(0) != total)
144 printf("Total Time:%10.7f Rate:%11.3fevals/sec Perf: %5.3fGFLOPS Expression: %s\n",
145 timer.time(),
146 rounds / timer.time(),
147 (rounds * vec_size * cost) / (1e+9 * timer.time()),
148 expression_string.c_str());
149 else
150 printf("run_expression_benchmark() - Error running benchmark for expression: %s\n",
151 expression_string.c_str());
152}
153
154template <typename T>
155void run_threaded_benchmark(const std::size_t& vec_size, const std::size_t& thread_count)
156{
157 std::vector<std::thread> thread_list;
158
159 exprtk::timer timer;
160
161 timer.start();
162
163 for (std::size_t i = 0; i < thread_count; ++i)
164 {
165 thread_list.emplace_back(
166 std::thread([vec_size]()
167 {
168 for (std::size_t e = 0; e < global_expression_list_size; ++e)
169 {
170 run_expression_benchmark<T>(
171 vec_size,
172 global_expression_list[e].expression,
173 global_expression_list[e].cost);
174 }
175 }));
176 }
177
178 for (auto& t : thread_list)
179 {
180 t.join();
181 }
182
183 timer.stop();
184
185 unsigned long long total_flops = 0;
186
187 for (std::size_t i = 0; i < global_expression_list_size; ++i)
188 {
189 total_flops += global_expression_list[i].cost;
190 }
191
192 total_flops = (total_flops * rounds * vec_size * thread_count);
193
194 printf("Total Time:%10.7f FLOP: %llu Perf: %7.4fGFLOPS\n",
195 timer.time(),
196 total_flops,
197 total_flops / (1e9 * timer.time()));
198}
199
200int main(int argc, char* argv[])
201{
202 const std::size_t vec_size = ((argc >= 2) ? atoi(argv[1]) : 100000);
203 const std::size_t thread_count = ((argc == 3) ? atoi(argv[2]) : 1 );
204
205 if (thread_count > 36)
206 return -1;
207
208 run_threaded_benchmark<double>(vec_size,thread_count);
209
210 return 0;
211}
212
213/*
214Build command:
215
216c++ -pedantic-errors -Wall -Wextra -Werror -Wno-long-long \
217-std=c++11 \
218-O3 -DNDEBUG -mtune=native -march=native -ftree-vectorize \
219-o exprtk_vector_benchmark_multithreaded \
220exprtk_vector_benchmark_multithreaded.cpp \
221-L/usr/lib -lstdc++ -lm -lpthread \
222
223*/
double time() const
Definition exprtk.hpp:43502
const std::size_t rounds
void run_threaded_benchmark(const std::size_t &vec_size, const std::size_t &thread_count)
void run_expression_benchmark(const std::size_t &vec_size, const std::string &expression_string, const std::size_t &cost)
const std::size_t global_expression_list_size
const test_expression global_expression_list[]
test_expression(const std::size_t c, const std::string &ex)