19edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes/*
29edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * Copyright (C) 2013 The Android Open Source Project
39edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes *
49edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
59edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * you may not use this file except in compliance with the License.
69edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * You may obtain a copy of the License at
79edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes *
89edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
99edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes *
109edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * Unless required by applicable law or agreed to in writing, software
119edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
129edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * See the License for the specific language governing permissions and
149edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes * limitations under the License.
159edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes */
169edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
17a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu#include <fenv.h>
189edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes#include <math.h>
199edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
20281e06ba69ce6f591697acf65a24651050809920Elliott Hughes#include <benchmark/benchmark.h>
21a7b0f8899790198cd9e72950f481679fe31e1a92Anders Lewis#include "util.h"
22df4942c04a63ae6e4f5c78ece9f696d6b8b74d32Christopher Ferris
23281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic const double values[] = { 1234.0, nan(""), HUGE_VAL, 0.0 };
24281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic const char* names[] = { "1234.0", "nan", "HUGE_VAL", "0.0" };
25281e06ba69ce6f591697acf65a24651050809920Elliott Hughes
26281e06ba69ce6f591697acf65a24651050809920Elliott Hughes
27281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void SetLabel(benchmark::State& state) {
28be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  state.SetLabel(names[state.range(0)]);
29281e06ba69ce6f591697acf65a24651050809920Elliott Hughes}
30df4942c04a63ae6e4f5c78ece9f696d6b8b74d32Christopher Ferris
319edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes// Avoid optimization.
32055a59c3ed3ecd8f3cac4aa5496f3d21ab56a131Dan Albertvolatile double d;
33055a59c3ed3ecd8f3cac4aa5496f3d21ab56a131Dan Albertvolatile double v;
349edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
35281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_sqrt(benchmark::State& state) {
369edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  d = 0.0;
379edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  v = 2.0;
38281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
399edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes    d += sqrt(v);
409edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  }
419edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes}
42a7b0f8899790198cd9e72950f481679fe31e1a92Anders LewisBIONIC_BENCHMARK(BM_math_sqrt);
439edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
44281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_log10(benchmark::State& state) {
459edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  d = 0.0;
469edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  v = 1234.0;
47281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
489edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes    d += log10(v);
499edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  }
509edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes}
51a7b0f8899790198cd9e72950f481679fe31e1a92Anders LewisBIONIC_BENCHMARK(BM_math_log10);
529edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
53281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_logb(benchmark::State& state) {
549edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  d = 0.0;
559edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  v = 1234.0;
56281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
579edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes    d += logb(v);
589edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  }
599edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes}
60a7b0f8899790198cd9e72950f481679fe31e1a92Anders LewisBIONIC_BENCHMARK(BM_math_logb);
6102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
62281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isfinite_macro(benchmark::State& state) {
63b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
64be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
65281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
66b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += isfinite(v);
67b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
68281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
69b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
70858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_isfinite_macro, "MATH_COMMON");
71b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
72281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isfinite(benchmark::State& state) {
73b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
74be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
75281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
765c6a7bf0dc821bcaa49d5289f01360f8dd78aa86Elliott Hughes    d += isfinite(v);
77b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
78281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
79b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
80858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_isfinite, "MATH_COMMON");
81b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
82281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isinf_macro(benchmark::State& state) {
83b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
84be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
85281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
86b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += isinf(v);
87b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
88281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
89b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
90858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_isinf_macro, "MATH_COMMON");
91b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
92281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isinf(benchmark::State& state) {
9302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
94be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
95281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
9602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += (isinf)(v);
9702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
98281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
9902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
100858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_isinf, "MATH_COMMON");
10102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
102281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isnan_macro(benchmark::State& state) {
103b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
104be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
105281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
106b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += isnan(v);
107b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
108281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
109b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
110858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_isnan_macro, "MATH_COMMON");
111b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
112281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isnan(benchmark::State& state) {
113b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
114be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
115281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
116b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += (isnan)(v);
117b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
118281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
119b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
120858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_isnan, "MATH_COMMON");
121b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
122281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isnormal_macro(benchmark::State& state) {
123b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
124be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
125281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
126b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += isnormal(v);
127b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
128281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
129b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
130858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_isnormal_macro, "MATH_COMMON");
131b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
132281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isnormal(benchmark::State& state) {
133b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
134be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
135281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
1365c6a7bf0dc821bcaa49d5289f01360f8dd78aa86Elliott Hughes    d += isnormal(v);
137b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
138281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
139b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
140858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_isnormal, "MATH_COMMON");
141b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
142281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_sin_fast(benchmark::State& state) {
143a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
144281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
145a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
146a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
147a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
148a7b0f8899790198cd9e72950f481679fe31e1a92Anders LewisBIONIC_BENCHMARK(BM_math_sin_fast);
14902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
150281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_sin_feupdateenv(benchmark::State& state) {
151a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
152281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
153a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fenv_t __libc_save_rm;
154a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feholdexcept(&__libc_save_rm);
155a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetround(FE_TONEAREST);
156a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
157a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feupdateenv(&__libc_save_rm);
158a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
159a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
160a7b0f8899790198cd9e72950f481679fe31e1a92Anders LewisBIONIC_BENCHMARK(BM_math_sin_feupdateenv);
161a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu
162281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_sin_fesetenv(benchmark::State& state) {
163a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
164281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
165a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fenv_t __libc_save_rm;
166a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feholdexcept(&__libc_save_rm);
167a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetround(FE_TONEAREST);
168a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
169a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetenv(&__libc_save_rm);
170a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
171a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
172a7b0f8899790198cd9e72950f481679fe31e1a92Anders LewisBIONIC_BENCHMARK(BM_math_sin_fesetenv);
17302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
174281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_fpclassify(benchmark::State& state) {
17502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
176be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
177281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
17802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += fpclassify(v);
17902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
180281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
18102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
182858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_fpclassify, "MATH_COMMON");
183b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
184281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_signbit_macro(benchmark::State& state) {
185b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
186be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
187281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
188b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += signbit(v);
189b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
190281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
191b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
192858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_signbit_macro, "MATH_COMMON");
193b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
194281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_signbit(benchmark::State& state) {
195b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
196be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
197281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
1985c6a7bf0dc821bcaa49d5289f01360f8dd78aa86Elliott Hughes    d += signbit(v);
199b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
200281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
201b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
202858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_signbit, "MATH_COMMON");
203f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes
204281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_fabs_macro(benchmark::State& state) {
205f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes  d = 0.0;
206be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
207281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
208f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes    d += fabs(v);
209f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes  }
210281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
211f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes}
212858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_fabs_macro, "MATH_COMMON");
213f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes
214281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_fabs(benchmark::State& state) {
215f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes  d = 0.0;
216be763d85c881b58754e650192204e8a2309660cbMartijn Coenen  v = values[state.range(0)];
217281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
218f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes    d += (fabs)(v);
219f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes  }
220281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
221f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes}
222858e33698d947a686fa59ed0206ce7c6656d3439Christopher FerrisBIONIC_BENCHMARK_WITH_ARG(BM_math_fabs, "MATH_COMMON");
223