1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <fenv.h>
18 #include <math.h>
19 
20 #include <benchmark/Benchmark.h>
21 
22 #define AT_COMMON_VALS \
23     Arg(1234.0)->Arg(nan(""))->Arg(HUGE_VAL)->Arg(0.0)
24 
25 // Avoid optimization.
26 volatile double d;
27 volatile double v;
28 
29 BENCHMARK_NO_ARG(BM_math_sqrt);
Run(int iters)30 void BM_math_sqrt::Run(int iters) {
31   StartBenchmarkTiming();
32 
33   d = 0.0;
34   v = 2.0;
35   for (int i = 0; i < iters; ++i) {
36     d += sqrt(v);
37   }
38 
39   StopBenchmarkTiming();
40 }
41 
42 BENCHMARK_NO_ARG(BM_math_log10);
Run(int iters)43 void BM_math_log10::Run(int iters) {
44   StartBenchmarkTiming();
45 
46   d = 0.0;
47   v = 1234.0;
48   for (int i = 0; i < iters; ++i) {
49     d += log10(v);
50   }
51 
52   StopBenchmarkTiming();
53 }
54 
55 BENCHMARK_NO_ARG(BM_math_logb);
Run(int iters)56 void BM_math_logb::Run(int iters) {
57   StartBenchmarkTiming();
58 
59   d = 0.0;
60   v = 1234.0;
61   for (int i = 0; i < iters; ++i) {
62     d += logb(v);
63   }
64 
65   StopBenchmarkTiming();
66 }
67 
68 BENCHMARK_WITH_ARG(BM_math_isinf, double)->AT_COMMON_VALS;
Run(int iters,double value)69 void BM_math_isinf::Run(int iters, double value) {
70   StartBenchmarkTiming();
71 
72   d = 0.0;
73   v = value;
74   for (int i = 0; i < iters; ++i) {
75     d += (isinf)(v);
76   }
77 
78   StopBenchmarkTiming();
79 }
80 
81 BENCHMARK_NO_ARG(BM_math_sin_fast);
Run(int iters)82 void BM_math_sin_fast::Run(int iters) {
83   StartBenchmarkTiming();
84 
85   d = 1.0;
86   for (int i = 0; i < iters; ++i) {
87     d += sin(d);
88   }
89 
90   StopBenchmarkTiming();
91 }
92 
93 BENCHMARK_NO_ARG(BM_math_sin_feupdateenv);
Run(int iters)94 void BM_math_sin_feupdateenv::Run(int iters) {
95   StartBenchmarkTiming();
96 
97   d = 1.0;
98   for (int i = 0; i < iters; ++i) {
99     fenv_t __libc_save_rm;
100     feholdexcept(&__libc_save_rm);
101     fesetround(FE_TONEAREST);
102     d += sin(d);
103     feupdateenv(&__libc_save_rm);
104   }
105 
106   StopBenchmarkTiming();
107 }
108 
109 BENCHMARK_NO_ARG(BM_math_sin_fesetenv);
Run(int iters)110 void BM_math_sin_fesetenv::Run(int iters) {
111   StartBenchmarkTiming();
112 
113   d = 1.0;
114   for (int i = 0; i < iters; ++i) {
115     fenv_t __libc_save_rm;
116     feholdexcept(&__libc_save_rm);
117     fesetround(FE_TONEAREST);
118     d += sin(d);
119     fesetenv(&__libc_save_rm);
120   }
121 
122   StopBenchmarkTiming();
123 }
124 
125 BENCHMARK_WITH_ARG(BM_math_fpclassify, double)->AT_COMMON_VALS;
Run(int iters,double value)126 void BM_math_fpclassify::Run(int iters, double value) {
127   StartBenchmarkTiming();
128 
129   d = 0.0;
130   v = value;
131   for (int i = 0; i < iters; ++i) {
132     d += fpclassify(v);
133   }
134 
135   StopBenchmarkTiming();
136 }
137