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 static const double values[] = { 1234.0, nan(""), HUGE_VAL, 0.0 };
23 static const char* names[] = { "1234.0", "nan", "HUGE_VAL", "0.0" };
24 
25 #define BENCHMARK_COMMON_VALS(name) BENCHMARK(name)->Arg(0)->Arg(1)->Arg(2)->Arg(3)
26 
SetLabel(benchmark::State & state)27 static void SetLabel(benchmark::State& state) {
28   state.SetLabel(names[state.range_x()]);
29 }
30 
31 // Avoid optimization.
32 volatile double d;
33 volatile double v;
34 
BM_math_sqrt(benchmark::State & state)35 static void BM_math_sqrt(benchmark::State& state) {
36   d = 0.0;
37   v = 2.0;
38   while (state.KeepRunning()) {
39     d += sqrt(v);
40   }
41 }
42 BENCHMARK(BM_math_sqrt);
43 
BM_math_log10(benchmark::State & state)44 static void BM_math_log10(benchmark::State& state) {
45   d = 0.0;
46   v = 1234.0;
47   while (state.KeepRunning()) {
48     d += log10(v);
49   }
50 }
51 BENCHMARK(BM_math_log10);
52 
BM_math_logb(benchmark::State & state)53 static void BM_math_logb(benchmark::State& state) {
54   d = 0.0;
55   v = 1234.0;
56   while (state.KeepRunning()) {
57     d += logb(v);
58   }
59 }
60 BENCHMARK(BM_math_logb);
61 
BM_math_isfinite_macro(benchmark::State & state)62 static void BM_math_isfinite_macro(benchmark::State& state) {
63   d = 0.0;
64   v = values[state.range_x()];
65   while (state.KeepRunning()) {
66     d += isfinite(v);
67   }
68   SetLabel(state);
69 }
70 BENCHMARK_COMMON_VALS(BM_math_isfinite_macro);
71 
72 #if defined(__BIONIC__)
73 #define test_isfinite __isfinite
74 #else
75 #define test_isfinite __finite
76 #endif
BM_math_isfinite(benchmark::State & state)77 static void BM_math_isfinite(benchmark::State& state) {
78   d = 0.0;
79   v = values[state.range_x()];
80   while (state.KeepRunning()) {
81     d += test_isfinite(v);
82   }
83   SetLabel(state);
84 }
85 BENCHMARK_COMMON_VALS(BM_math_isfinite);
86 
BM_math_isinf_macro(benchmark::State & state)87 static void BM_math_isinf_macro(benchmark::State& state) {
88   d = 0.0;
89   v = values[state.range_x()];
90   while (state.KeepRunning()) {
91     d += isinf(v);
92   }
93   SetLabel(state);
94 }
95 BENCHMARK_COMMON_VALS(BM_math_isinf_macro);
96 
BM_math_isinf(benchmark::State & state)97 static void BM_math_isinf(benchmark::State& state) {
98   d = 0.0;
99   v = values[state.range_x()];
100   while (state.KeepRunning()) {
101     d += (isinf)(v);
102   }
103   SetLabel(state);
104 }
105 BENCHMARK_COMMON_VALS(BM_math_isinf);
106 
BM_math_isnan_macro(benchmark::State & state)107 static void BM_math_isnan_macro(benchmark::State& state) {
108   d = 0.0;
109   v = values[state.range_x()];
110   while (state.KeepRunning()) {
111     d += isnan(v);
112   }
113   SetLabel(state);
114 }
115 BENCHMARK_COMMON_VALS(BM_math_isnan_macro);
116 
BM_math_isnan(benchmark::State & state)117 static void BM_math_isnan(benchmark::State& state) {
118   d = 0.0;
119   v = values[state.range_x()];
120   while (state.KeepRunning()) {
121     d += (isnan)(v);
122   }
123   SetLabel(state);
124 }
125 BENCHMARK_COMMON_VALS(BM_math_isnan);
126 
BM_math_isnormal_macro(benchmark::State & state)127 static void BM_math_isnormal_macro(benchmark::State& state) {
128   d = 0.0;
129   v = values[state.range_x()];
130   while (state.KeepRunning()) {
131     d += isnormal(v);
132   }
133   SetLabel(state);
134 }
135 BENCHMARK_COMMON_VALS(BM_math_isnormal_macro);
136 
137 #if defined(__BIONIC__)
BM_math_isnormal(benchmark::State & state)138 static void BM_math_isnormal(benchmark::State& state) {
139   d = 0.0;
140   v = values[state.range_x()];
141   while (state.KeepRunning()) {
142     d += (__isnormal)(v);
143   }
144   SetLabel(state);
145 }
146 BENCHMARK_COMMON_VALS(BM_math_isnormal);
147 #endif
148 
BM_math_sin_fast(benchmark::State & state)149 static void BM_math_sin_fast(benchmark::State& state) {
150   d = 1.0;
151   while (state.KeepRunning()) {
152     d += sin(d);
153   }
154 }
155 BENCHMARK(BM_math_sin_fast);
156 
BM_math_sin_feupdateenv(benchmark::State & state)157 static void BM_math_sin_feupdateenv(benchmark::State& state) {
158   d = 1.0;
159   while (state.KeepRunning()) {
160     fenv_t __libc_save_rm;
161     feholdexcept(&__libc_save_rm);
162     fesetround(FE_TONEAREST);
163     d += sin(d);
164     feupdateenv(&__libc_save_rm);
165   }
166 }
167 BENCHMARK(BM_math_sin_feupdateenv);
168 
BM_math_sin_fesetenv(benchmark::State & state)169 static void BM_math_sin_fesetenv(benchmark::State& state) {
170   d = 1.0;
171   while (state.KeepRunning()) {
172     fenv_t __libc_save_rm;
173     feholdexcept(&__libc_save_rm);
174     fesetround(FE_TONEAREST);
175     d += sin(d);
176     fesetenv(&__libc_save_rm);
177   }
178 }
179 BENCHMARK(BM_math_sin_fesetenv);
180 
BM_math_fpclassify(benchmark::State & state)181 static void BM_math_fpclassify(benchmark::State& state) {
182   d = 0.0;
183   v = values[state.range_x()];
184   while (state.KeepRunning()) {
185     d += fpclassify(v);
186   }
187   SetLabel(state);
188 }
189 BENCHMARK_COMMON_VALS(BM_math_fpclassify);
190 
BM_math_signbit_macro(benchmark::State & state)191 static void BM_math_signbit_macro(benchmark::State& state) {
192   d = 0.0;
193   v = values[state.range_x()];
194   while (state.KeepRunning()) {
195     d += signbit(v);
196   }
197   SetLabel(state);
198 }
199 BENCHMARK_COMMON_VALS(BM_math_signbit_macro);
200 
BM_math_signbit(benchmark::State & state)201 static void BM_math_signbit(benchmark::State& state) {
202   d = 0.0;
203   v = values[state.range_x()];
204   while (state.KeepRunning()) {
205     d += (__signbit)(v);
206   }
207   SetLabel(state);
208 }
209 BENCHMARK_COMMON_VALS(BM_math_signbit);
210 
BM_math_fabs_macro(benchmark::State & state)211 static void BM_math_fabs_macro(benchmark::State& state) {
212   d = 0.0;
213   v = values[state.range_x()];
214   while (state.KeepRunning()) {
215     d += fabs(v);
216   }
217   SetLabel(state);
218 }
219 BENCHMARK_COMMON_VALS(BM_math_fabs_macro);
220 
BM_math_fabs(benchmark::State & state)221 static void BM_math_fabs(benchmark::State& state) {
222   d = 0.0;
223   v = values[state.range_x()];
224   while (state.KeepRunning()) {
225     d += (fabs)(v);
226   }
227   SetLabel(state);
228 }
229 BENCHMARK_COMMON_VALS(BM_math_fabs);
230