• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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