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