1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2023. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cmath"
17 #include "util.h"
18
19 using namespace std;
20
21 constexpr double PI = 3.14159265;
22 constexpr double FLT_MIN = 1.175494351e-38F;
23
24 static const double DOUBLE_VALUES[] = { 0.1, 10.0, -100.0, 0.0001, 5.14e11, -0.0001, 10000000.0, -100000000.0 };
25 static const double COSSIN_VALUES[] = { -334.143, -2.0, -1.0, 0.0, 0.5, 1.0, 243.01, 3.14 };
26 static const long double DIVIDEND_VALUES[] = { 10.5L, -10.5L, 2.71L, -2.71L, 3.14159265358979323846L,
27 -3.14159265358979323846L, 1.0 / 3.0L, -1.0 / 3.0L };
28 static const long double DIVISOR_VALUES[] = { 3.0L, -3.0L, 1.414L, -1.414L, 0.5L, -0.5L,
29 2.7182818284590452354L, -2.7182818284590452354L };
30
31 static const double FLOAT_VALUES[] = { 0.1, 10.0, -100.0, 0.0001, 5.14e11, -0.0001, 10000000.0, -100000000.0 };
32 static const double ATANHF_FLOAT_VALUES[] = { -1.0, -0.0, 0.0, -0.5, 0.9, 1.0, -100, 1000000.0 };
33 static const double RINTF_FLOAT_VALUES[] = { -3.52467, 0.0, 2.0 / 0.0, 3.37562, 3.76542 };
34 static const float LOGF_VALUES[] = { 0.0, static_cast<float>(0.0 / 0.0), 20.0, static_cast<float>(9.6 / 0.0), 0.0001, 5.14e11, -1.0, -100 };
35 // The function generates a value that has the size of the parameter x and the symbol of the parameter y
Bm_function_Copysignl_Allpositive(benchmark::State & state)36 static void Bm_function_Copysignl_Allpositive(benchmark::State &state)
37 {
38 long double x = 2417851639229258349412352.000000;
39 long double y = 6051711999279104.000000;
40 for (auto _ : state) {
41 benchmark::DoNotOptimize(copysignl(x, y));
42 }
43 }
44
Bm_function_Copysignl_Allnegative(benchmark::State & state)45 static void Bm_function_Copysignl_Allnegative(benchmark::State &state)
46 {
47 long double x = -2417851639229258349412352.000000;
48 long double y = -6051711999279104.000000;
49 for (auto _ : state) {
50 benchmark::DoNotOptimize(copysignl(x, y));
51 }
52 }
53
Bm_function_Copysignl_Np(benchmark::State & state)54 static void Bm_function_Copysignl_Np(benchmark::State &state)
55 {
56 long double x = -2417851639229258349412352.000000;
57 long double y = 6051711999279104.000000;
58 for (auto _ : state) {
59 benchmark::DoNotOptimize(copysignl(x, y));
60 }
61 }
62
Bm_function_Copysignl_Pn(benchmark::State & state)63 static void Bm_function_Copysignl_Pn(benchmark::State &state)
64 {
65 long double x = 2417851639229258349412352.000000;
66 long double y = -6051711999279104.000000;
67 for (auto _ : state) {
68 benchmark::DoNotOptimize(copysignl(x, y));
69 }
70 }
71
72 // remainder(long doubel)
Bm_function_Fmodl(benchmark::State & state)73 static void Bm_function_Fmodl(benchmark::State &state)
74 {
75 long double x = DIVIDEND_VALUES[state.range(0)];
76 long double y = DIVISOR_VALUES[state.range(0)];
77 for (auto _ : state) {
78 benchmark::DoNotOptimize(fmodl(x, y));
79 }
80 }
81
Bm_function_Fmodf(benchmark::State & state)82 static void Bm_function_Fmodf(benchmark::State &state)
83 {
84 float x = DIVIDEND_VALUES[state.range(0)];
85 float y = DIVISOR_VALUES[state.range(0)];
86 for (auto _ : state) {
87 benchmark::DoNotOptimize(fmodf(x, y));
88 }
89 }
90 // The 3.14th power of e
Bm_function_Exp(benchmark::State & state)91 static void Bm_function_Exp(benchmark::State &state)
92 {
93 double x = DOUBLE_VALUES[state.range(0)];
94 for (auto _ : state) {
95 benchmark::DoNotOptimize(exp(x));
96 }
97 }
98
99 // The logarithm of base e and x
Bm_function_Log(benchmark::State & state)100 static void Bm_function_Log(benchmark::State &state)
101 {
102 double x = DOUBLE_VALUES[state.range(0)];
103 for (auto _ : state) {
104 benchmark::DoNotOptimize(log(x));
105 }
106 }
107
108 // Returns the cosine of the radian angle x
Bm_function_Cos(benchmark::State & state)109 static void Bm_function_Cos(benchmark::State &state)
110 {
111 double x = COSSIN_VALUES[state.range(0)];
112 double val = PI / 180.0;
113 for (auto _ : state) {
114 benchmark::DoNotOptimize(cos(x * val));
115 }
116 }
117
118 // Break floating point number into mantissa and exponent
Bm_function_Frexpl(benchmark::State & state)119 static void Bm_function_Frexpl(benchmark::State &state)
120 {
121 long double x = DIVIDEND_VALUES[state.range(0)];
122 int e;
123 for (auto _ : state) {
124 benchmark::DoNotOptimize(frexpl(x, &e));
125 }
126 }
127
128 // x * 2 ^ n
Bm_function_Scalbn1(benchmark::State & state)129 static void Bm_function_Scalbn1(benchmark::State &state)
130 {
131 double x = 3.8;
132 int n = 1024;
133 for (auto _ : state) {
134 benchmark::DoNotOptimize(scalbn(x, n));
135 }
136 state.SetItemsProcessed(state.iterations());
137 }
138
139 // x * 2 ^ n
Bm_function_Scalbn2(benchmark::State & state)140 static void Bm_function_Scalbn2(benchmark::State &state)
141 {
142 double x = 10.9;
143 int n = -1023;
144 for (auto _ : state) {
145 benchmark::DoNotOptimize(scalbn(x, n));
146 }
147 state.SetItemsProcessed(state.iterations());
148 }
149
150 // x * 2 ^ n
Bm_function_Scalbn3(benchmark::State & state)151 static void Bm_function_Scalbn3(benchmark::State &state)
152 {
153 double x = -100.9;
154 int n = -100;
155 for (auto _ : state) {
156 benchmark::DoNotOptimize(scalbn(x, n));
157 }
158 state.SetItemsProcessed(state.iterations());
159 }
160
161 // x * 2 ^ n
Bm_function_Scalbn4(benchmark::State & state)162 static void Bm_function_Scalbn4(benchmark::State &state)
163 {
164 double x = -100.9;
165 int n = 100;
166 for (auto _ : state) {
167 benchmark::DoNotOptimize(scalbn(x, n));
168 }
169 state.SetItemsProcessed(state.iterations());
170 }
171
172 // x * 2 ^ n
Bm_function_Scalbnl1(benchmark::State & state)173 static void Bm_function_Scalbnl1(benchmark::State &state)
174 {
175 long double x = static_cast<long double>(2e-10);
176 int n = -16384;
177 for (auto _ : state) {
178 benchmark::DoNotOptimize(scalbnl(x, n));
179 }
180 state.SetItemsProcessed(state.iterations());
181 }
182
183 // x * 2 ^ n
Bm_function_Scalbnl2(benchmark::State & state)184 static void Bm_function_Scalbnl2(benchmark::State &state)
185 {
186 long double x = static_cast<long double>(2e-10);
187 int n = 16384;
188
189 for (auto _ : state) {
190 benchmark::DoNotOptimize(scalbnl(x, n));
191 }
192 state.SetItemsProcessed(state.iterations());
193 }
194
195 // x * 2 ^ n
Bm_function_Scalbnl3(benchmark::State & state)196 static void Bm_function_Scalbnl3(benchmark::State &state)
197 {
198 long double x = -PI;
199 int n = 1000;
200
201 for (auto _ : state) {
202 benchmark::DoNotOptimize(scalbnl(x, n));
203 }
204 state.SetItemsProcessed(state.iterations());
205 }
206
207 // x * 2 ^ n
Bm_function_Scalbnl4(benchmark::State & state)208 static void Bm_function_Scalbnl4(benchmark::State &state)
209 {
210 long double x = -PI;
211 int n = -1000;
212
213 for (auto _ : state) {
214 benchmark::DoNotOptimize(scalbnl(x, n));
215 }
216 state.SetItemsProcessed(state.iterations());
217 }
218
Bm_function_Scalbnf1(benchmark::State & state)219 static void Bm_function_Scalbnf1(benchmark::State &state)
220 {
221 float x = 3.8;
222 int n = 1024;
223 for (auto _ : state) {
224 benchmark::DoNotOptimize(scalbnf(x, n));
225 }
226 state.SetItemsProcessed(state.iterations());
227 }
228
Bm_function_Scalbnf2(benchmark::State & state)229 static void Bm_function_Scalbnf2(benchmark::State &state)
230 {
231 float x = 10.9;
232 int n = -1023;
233 for (auto _ : state) {
234 benchmark::DoNotOptimize(scalbnf(x, n));
235 }
236 state.SetItemsProcessed(state.iterations());
237 }
238
Bm_function_Scalbnf3(benchmark::State & state)239 static void Bm_function_Scalbnf3(benchmark::State &state)
240 {
241 float x = -3.8;
242 int n = 1024;
243 for (auto _ : state) {
244 benchmark::DoNotOptimize(scalbnf(x, n));
245 }
246 state.SetItemsProcessed(state.iterations());
247 }
248
Bm_function_Scalbnf4(benchmark::State & state)249 static void Bm_function_Scalbnf4(benchmark::State &state)
250 {
251 float x = -10.9;
252 int n = -1023;
253 for (auto _ : state) {
254 benchmark::DoNotOptimize(scalbnf(x, n));
255 }
256 state.SetItemsProcessed(state.iterations());
257 }
258
259 // remainder
Bm_function_Fmod(benchmark::State & state)260 static void Bm_function_Fmod(benchmark::State &state)
261 {
262 double x = (double)DIVIDEND_VALUES[state.range(0)];
263 double y = (double)DIVISOR_VALUES[state.range(0)];
264 for (auto _ : state) {
265 benchmark::DoNotOptimize(fmod(x, y));
266 }
267 }
268
269 // Returns the sine of the radian angle x
Bm_function_Sin(benchmark::State & state)270 static void Bm_function_Sin(benchmark::State &state)
271 {
272 double x = COSSIN_VALUES[state.range(0)];
273 double val = PI / 180.0;
274 for (auto _ : state) {
275 benchmark::DoNotOptimize(sin(x*val));
276 }
277 }
278
Bm_function_Atanf(benchmark::State & state)279 static void Bm_function_Atanf(benchmark::State &state)
280 {
281 float x = ATANHF_FLOAT_VALUES[state.range(0)];
282 for (auto _ : state) {
283 benchmark::DoNotOptimize(atanf(x));
284 }
285 }
286
Bm_function_Atan2f(benchmark::State & state)287 static void Bm_function_Atan2f(benchmark::State &state)
288 {
289 float x = DIVIDEND_VALUES[state.range(0)];
290 float y = DIVISOR_VALUES[state.range(0)];
291 for (auto _ : state) {
292 benchmark::DoNotOptimize(atan2f(x, y));
293 }
294 }
295
296 // FP_INFINITE The specified value is positive or negative infinity
Bm_function_fpclassifyl(benchmark::State & state)297 static void Bm_function_fpclassifyl(benchmark::State &state)
298 {
299 long double x = log(0.0);
300 for (auto _ : state) {
301 benchmark::DoNotOptimize(fpclassify(x));
302 }
303 state.SetItemsProcessed(state.iterations());
304 }
305
306 // FP_SUBNORMAL The specified value is a positive or negative normalization value
Bm_function_fpclassifyl1(benchmark::State & state)307 static void Bm_function_fpclassifyl1(benchmark::State &state)
308 {
309 long double x = (FLT_MIN / 2.0);
310 for (auto _ : state) {
311 benchmark::DoNotOptimize(fpclassify(x));
312 }
313 state.SetItemsProcessed(state.iterations());
314 }
315
316 // FP_NAN The specified value is not a number
Bm_function_fpclassifyl2(benchmark::State & state)317 static void Bm_function_fpclassifyl2(benchmark::State &state)
318 {
319 long double x = sqrt(-1.0);
320 for (auto _ : state) {
321 benchmark::DoNotOptimize(fpclassify(x));
322 }
323 state.SetItemsProcessed(state.iterations());
324 }
325
326 // FP_ZERO Specify a value of zero
Bm_function_fpclassifyl3(benchmark::State & state)327 static void Bm_function_fpclassifyl3(benchmark::State &state)
328 {
329 long double x = -0.0;
330 for (auto _ : state) {
331 benchmark::DoNotOptimize(fpclassify(x));
332 }
333 state.SetItemsProcessed(state.iterations());
334 }
335
Bm_function_Expm1(benchmark::State & state)336 static void Bm_function_Expm1(benchmark::State &state)
337 {
338 double x = DOUBLE_VALUES[state.range(0)];
339 for (auto _ : state) {
340 benchmark::DoNotOptimize(expm1(x));
341 }
342 state.SetItemsProcessed(state.iterations());
343 }
344
345 // Rounds up one floating-point number
Bm_function_Ceilf(benchmark::State & state)346 static void Bm_function_Ceilf(benchmark::State &state)
347 {
348 float a = (float)DOUBLE_VALUES[state.range(0)];
349 for (auto _ : state) {
350 benchmark::DoNotOptimize(ceilf(a));
351 }
352 }
353
354 // Returns the largest integer value less than or equal to the input value
Bm_function_Floor(benchmark::State & state)355 static void Bm_function_Floor(benchmark::State &state)
356 {
357 double a = DOUBLE_VALUES[state.range(0)];
358 for (auto _ : state) {
359 benchmark::DoNotOptimize(floor(a));
360 }
361 }
362
363 // The logarithmic value used to calculate the gamma function
Bm_function_Lgammaf(benchmark::State & state)364 static void Bm_function_Lgammaf(benchmark::State &state)
365 {
366 float a = (float)DOUBLE_VALUES[state.range(0)];
367 for (auto _ : state) {
368 benchmark::DoNotOptimize(lgammaf(a));
369 }
370 }
371
Bm_function_Erfcf(benchmark::State & state)372 static void Bm_function_Erfcf(benchmark::State &state)
373 {
374 float a = (float)DOUBLE_VALUES[state.range(0)];
375 for (auto _ : state) {
376 benchmark::DoNotOptimize(erfcf(a));
377 }
378 }
379
Bm_function_Ilogbf(benchmark::State & state)380 static void Bm_function_Ilogbf(benchmark::State &state)
381 {
382 float a = (float)DOUBLE_VALUES[state.range(0)];
383 for (auto _ : state) {
384 benchmark::DoNotOptimize(ilogbf(a));
385 }
386 }
387
388 // Used to perform multiplication and addition operations on floating-point numbers
389 // a * b + c
Bm_function_Fmaf(benchmark::State & state)390 static void Bm_function_Fmaf(benchmark::State &state)
391 {
392 srand(time(nullptr));
393 for (int i = 0; i <= state.range(0); i++) {
394 for (auto _ : state) {
395 float a = (float)DOUBLE_VALUES[rand() % 8];
396 float b = (float)DOUBLE_VALUES[(rand()+1) % 8];
397 float c = (float)DOUBLE_VALUES[(rand()+2) % 8];
398 benchmark::DoNotOptimize(fmaf(a, b, c));
399 }
400 }
401 }
402
403 // create a floating-point number that represents a non-numeric value
Bm_function_Nan(benchmark::State & state)404 static void Bm_function_Nan(benchmark::State &state)
405 {
406 for (auto _ : state) {
407 benchmark::DoNotOptimize(nan("5.14e11"));
408 }
409 }
410
Bm_function_Nan_null(benchmark::State & state)411 static void Bm_function_Nan_null(benchmark::State &state)
412 {
413 for (auto _ : state) {
414 benchmark::DoNotOptimize(nan(""));
415 }
416 }
417
Bm_function_Acoshf(benchmark::State & state)418 static void Bm_function_Acoshf(benchmark::State &state)
419 {
420 float a = COSSIN_VALUES[state.range(0)];
421 for (auto _ : state) {
422 benchmark::DoNotOptimize(acoshf(a));
423 }
424 }
425
Bm_function_Asinhf(benchmark::State & state)426 static void Bm_function_Asinhf(benchmark::State &state)
427 {
428 float a = COSSIN_VALUES[state.range(0)];
429 for (auto _ : state) {
430 benchmark::DoNotOptimize(asinhf(a));
431 }
432 }
433
Bm_function_Modff(benchmark::State & state)434 static void Bm_function_Modff(benchmark::State &state)
435 {
436 float value = (float)COSSIN_VALUES[state.range(0)];
437 float ipart;
438 for (auto _ : state) {
439 benchmark::DoNotOptimize(modff(value, &ipart));
440 }
441 }
442
Bm_function_Llroundf(benchmark::State & state)443 static void Bm_function_Llroundf(benchmark::State &state)
444 {
445 float x = (float)DOUBLE_VALUES[state.range(0)];
446 for (auto _ : state) {
447 benchmark::DoNotOptimize(llroundf(x));
448 }
449 }
450
Bm_function_Logbf(benchmark::State & state)451 static void Bm_function_Logbf(benchmark::State &state)
452 {
453 float x = LOGF_VALUES[state.range(0)];
454 for (auto _ : state) {
455 benchmark::DoNotOptimize(logbf(x));
456 }
457 }
458
Bm_function_Log10f(benchmark::State & state)459 static void Bm_function_Log10f(benchmark::State &state)
460 {
461 float x = LOGF_VALUES[state.range(0)];
462 for (auto _ : state) {
463 benchmark::DoNotOptimize(log10f(x));
464 }
465 }
466
Bm_function_Expm1f(benchmark::State & state)467 static void Bm_function_Expm1f(benchmark::State &state)
468 {
469 float x = FLOAT_VALUES[state.range(0)];
470 for (auto _ : state) {
471 benchmark::DoNotOptimize(expm1f(x));
472 }
473 }
474
Bm_function_Atanhf(benchmark::State & state)475 static void Bm_function_Atanhf(benchmark::State &state)
476 {
477 float x = ATANHF_FLOAT_VALUES[state.range(0)];
478 for (auto _ : state) {
479 benchmark::DoNotOptimize(atanhf(x));
480 }
481 }
482
Bm_function_Rintf(benchmark::State & state)483 static void Bm_function_Rintf(benchmark::State &state)
484 {
485 float x = RINTF_FLOAT_VALUES[state.range(0)];
486 for (auto _ : state) {
487 benchmark::DoNotOptimize(rintf(x));
488 }
489 }
490
Bm_function_Log1pf(benchmark::State & state)491 static void Bm_function_Log1pf(benchmark::State &state)
492 {
493 float a = (float)DOUBLE_VALUES[state.range(0)];
494 for (auto _ : state) {
495 benchmark::DoNotOptimize(log1pf(a));
496 }
497 }
498
499 MUSL_BENCHMARK(Bm_function_Copysignl_Allpositive);
500 MUSL_BENCHMARK(Bm_function_Copysignl_Allnegative);
501 MUSL_BENCHMARK(Bm_function_Copysignl_Np);
502 MUSL_BENCHMARK(Bm_function_Copysignl_Pn);
503 MUSL_BENCHMARK_WITH_ARG(Bm_function_Fmodl, "BENCHMARK_8");
504 MUSL_BENCHMARK_WITH_ARG(Bm_function_Fmodf, "BENCHMARK_8");
505 MUSL_BENCHMARK_WITH_ARG(Bm_function_Log, "BENCHMARK_8");
506 MUSL_BENCHMARK_WITH_ARG(Bm_function_Cos, "BENCHMARK_8");
507 MUSL_BENCHMARK_WITH_ARG(Bm_function_Frexpl, "BENCHMARK_8");
508 MUSL_BENCHMARK(Bm_function_Scalbn1);
509 MUSL_BENCHMARK(Bm_function_Scalbn2);
510 MUSL_BENCHMARK(Bm_function_Scalbn3);
511 MUSL_BENCHMARK(Bm_function_Scalbn4);
512 MUSL_BENCHMARK(Bm_function_Scalbnl1);
513 MUSL_BENCHMARK(Bm_function_Scalbnl2);
514 MUSL_BENCHMARK(Bm_function_Scalbnl3);
515 MUSL_BENCHMARK(Bm_function_Scalbnl4);
516 MUSL_BENCHMARK(Bm_function_Scalbnf1);
517 MUSL_BENCHMARK(Bm_function_Scalbnf2);
518 MUSL_BENCHMARK(Bm_function_Scalbnf3);
519 MUSL_BENCHMARK(Bm_function_Scalbnf4);
520 MUSL_BENCHMARK_WITH_ARG(Bm_function_Fmod, "BENCHMARK_8");
521 MUSL_BENCHMARK_WITH_ARG(Bm_function_Sin, "BENCHMARK_8");
522 MUSL_BENCHMARK_WITH_ARG(Bm_function_Atanf, "BENCHMARK_8");
523 MUSL_BENCHMARK_WITH_ARG(Bm_function_Atan2f, "BENCHMARK_8");
524 MUSL_BENCHMARK(Bm_function_fpclassifyl);
525 MUSL_BENCHMARK(Bm_function_fpclassifyl1);
526 MUSL_BENCHMARK(Bm_function_fpclassifyl2);
527 MUSL_BENCHMARK(Bm_function_fpclassifyl3);
528 MUSL_BENCHMARK_WITH_ARG(Bm_function_Expm1, "BENCHMARK_8");
529 MUSL_BENCHMARK_WITH_ARG(Bm_function_Exp, "BENCHMARK_8");
530 MUSL_BENCHMARK_WITH_ARG(Bm_function_Ceilf, "BENCHMARK_8");
531 MUSL_BENCHMARK_WITH_ARG(Bm_function_Floor, "BENCHMARK_8");
532 MUSL_BENCHMARK_WITH_ARG(Bm_function_Lgammaf, "BENCHMARK_8");
533 MUSL_BENCHMARK_WITH_ARG(Bm_function_Erfcf, "BENCHMARK_8");
534 MUSL_BENCHMARK_WITH_ARG(Bm_function_Ilogbf, "BENCHMARK_8");
535 MUSL_BENCHMARK_WITH_ARG(Bm_function_Fmaf, "BENCHMARK_8");
536 MUSL_BENCHMARK(Bm_function_Nan);
537 MUSL_BENCHMARK(Bm_function_Nan_null);
538 MUSL_BENCHMARK_WITH_ARG(Bm_function_Acoshf, "BENCHMARK_8");
539 MUSL_BENCHMARK_WITH_ARG(Bm_function_Asinhf, "BENCHMARK_8");
540 MUSL_BENCHMARK_WITH_ARG(Bm_function_Modff, "BENCHMARK_8");
541 MUSL_BENCHMARK_WITH_ARG(Bm_function_Llroundf, "BENCHMARK_8");
542 MUSL_BENCHMARK_WITH_ARG(Bm_function_Logbf, "BENCHMARK_8");
543 MUSL_BENCHMARK_WITH_ARG(Bm_function_Log10f, "BENCHMARK_8");
544 MUSL_BENCHMARK_WITH_ARG(Bm_function_Expm1f, "BENCHMARK_8");
545 MUSL_BENCHMARK_WITH_ARG(Bm_function_Atanhf, "BENCHMARK_8");
546 MUSL_BENCHMARK_WITH_ARG(Bm_function_Rintf, "BENCHMARK_5");
547 MUSL_BENCHMARK_WITH_ARG(Bm_function_Log1pf, "BENCHMARK_8");
548