math_benchmark.cpp revision 281e06ba69ce6f591697acf65a24651050809920
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>
21df4942c04a63ae6e4f5c78ece9f696d6b8b74d32Christopher Ferris
22281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic const double values[] = { 1234.0, nan(""), HUGE_VAL, 0.0 };
23281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic const char* names[] = { "1234.0", "nan", "HUGE_VAL", "0.0" };
24281e06ba69ce6f591697acf65a24651050809920Elliott Hughes
25281e06ba69ce6f591697acf65a24651050809920Elliott Hughes#define BENCHMARK_COMMON_VALS(name) BENCHMARK(name)->Arg(0)->Arg(1)->Arg(2)->Arg(3)
26281e06ba69ce6f591697acf65a24651050809920Elliott Hughes
27281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void SetLabel(benchmark::State& state) {
28281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  state.SetLabel(names[state.range_x()]);
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}
42281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK(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}
51281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK(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}
60281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK(BM_math_logb);
6102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
62281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isfinite_macro(benchmark::State& state) {
63b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
64281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
65281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
66b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += isfinite(v);
67b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
68281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
69b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
70281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_isfinite_macro);
71b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
72b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes#if defined(__BIONIC__)
73b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes#define test_isfinite __isfinite
74b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes#else
75b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes#define test_isfinite __finite
76b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes#endif
77281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isfinite(benchmark::State& state) {
78b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
79281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
80281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
81b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += test_isfinite(v);
82b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
83281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
84b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
85281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_isfinite);
86b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
87281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isinf_macro(benchmark::State& state) {
88b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
89281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
90281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
91b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += isinf(v);
92b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
93281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
94b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
95281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_isinf_macro);
96b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
97281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isinf(benchmark::State& state) {
9802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
99281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
100281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
10102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += (isinf)(v);
10202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
103281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
10402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
105281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_isinf);
10602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
107281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isnan_macro(benchmark::State& state) {
108b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
109281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
110281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
111b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += isnan(v);
112b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
113281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
114b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
115281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_isnan_macro);
116b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
117281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isnan(benchmark::State& state) {
118b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
119281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
120281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
121b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += (isnan)(v);
122b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
123281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
124b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
125281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_isnan);
126b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
127281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isnormal_macro(benchmark::State& state) {
128b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
129281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
130281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
131b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += isnormal(v);
132b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
133281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
134b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
135281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_isnormal_macro);
136b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
137b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes#if defined(__BIONIC__)
138281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_isnormal(benchmark::State& state) {
139b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
140281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
141281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
142b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += (__isnormal)(v);
143b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
144281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
145b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
146281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_isnormal);
147b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes#endif
148b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
149281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_sin_fast(benchmark::State& state) {
150a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
151281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
152a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
153a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
154a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
155281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK(BM_math_sin_fast);
15602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
157281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_sin_feupdateenv(benchmark::State& state) {
158a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
159281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
160a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fenv_t __libc_save_rm;
161a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feholdexcept(&__libc_save_rm);
162a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetround(FE_TONEAREST);
163a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
164a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feupdateenv(&__libc_save_rm);
165a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
166a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
167281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK(BM_math_sin_feupdateenv);
168a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu
169281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_sin_fesetenv(benchmark::State& state) {
170a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
171281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
172a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fenv_t __libc_save_rm;
173a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feholdexcept(&__libc_save_rm);
174a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetround(FE_TONEAREST);
175a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
176a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetenv(&__libc_save_rm);
177a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
178a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
179281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK(BM_math_sin_fesetenv);
18002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
181281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_fpclassify(benchmark::State& state) {
18202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
183281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
184281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
18502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += fpclassify(v);
18602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
187281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
18802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
189281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_fpclassify);
190b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
191281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_signbit_macro(benchmark::State& state) {
192b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
193281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
194281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
195b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += signbit(v);
196b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
197281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
198b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
199281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_signbit_macro);
200b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes
201281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_signbit(benchmark::State& state) {
202b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  d = 0.0;
203281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
204281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
205b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes    d += (__signbit)(v);
206b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes  }
207281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
208b662280aaff801ef936fbfab34dd1596acce945eElliott Hughes}
209281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_signbit);
210f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes
211281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_fabs_macro(benchmark::State& state) {
212f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes  d = 0.0;
213281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
214281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
215f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes    d += fabs(v);
216f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes  }
217281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
218f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes}
219281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_fabs_macro);
220f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes
221281e06ba69ce6f591697acf65a24651050809920Elliott Hughesstatic void BM_math_fabs(benchmark::State& state) {
222f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes  d = 0.0;
223281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  v = values[state.range_x()];
224281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  while (state.KeepRunning()) {
225f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes    d += (fabs)(v);
226f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes  }
227281e06ba69ce6f591697acf65a24651050809920Elliott Hughes  SetLabel(state);
228f9f4a432ee4f56b8cb24b2033d3b1068200a6d30Elliott Hughes}
229281e06ba69ce6f591697acf65a24651050809920Elliott HughesBENCHMARK_COMMON_VALS(BM_math_fabs);
230