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
179edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes#include "benchmark.h"
189edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
19a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu#include <fenv.h>
209edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes#include <math.h>
219edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
229edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes// Avoid optimization.
239edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughesdouble d;
249edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughesdouble v;
259edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
269edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughesstatic void BM_math_sqrt(int iters) {
279edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  StartBenchmarkTiming();
289edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
299edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  d = 0.0;
309edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  v = 2.0;
319edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  for (int i = 0; i < iters; ++i) {
329edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes    d += sqrt(v);
339edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  }
349edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
359edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  StopBenchmarkTiming();
369edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes}
379edb3e004b487e08cbbb54f2af18b15241550513Elliott HughesBENCHMARK(BM_math_sqrt);
389edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
399edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughesstatic void BM_math_log10(int iters) {
409edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  StartBenchmarkTiming();
419edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
429edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  d = 0.0;
439edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  v = 1234.0;
449edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  for (int i = 0; i < iters; ++i) {
459edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes    d += log10(v);
469edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  }
479edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
489edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  StopBenchmarkTiming();
499edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes}
509edb3e004b487e08cbbb54f2af18b15241550513Elliott HughesBENCHMARK(BM_math_log10);
519edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
529edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughesstatic void BM_math_logb(int iters) {
539edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  StartBenchmarkTiming();
549edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
559edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  d = 0.0;
569edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  v = 1234.0;
579edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  for (int i = 0; i < iters; ++i) {
589edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes    d += logb(v);
599edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  }
609edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes
619edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes  StopBenchmarkTiming();
629edb3e004b487e08cbbb54f2af18b15241550513Elliott Hughes}
639edb3e004b487e08cbbb54f2af18b15241550513Elliott HughesBENCHMARK(BM_math_logb);
6402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
6502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughesstatic void BM_math_isinf_NORMAL(int iters) {
6602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StartBenchmarkTiming();
6702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
6802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
6902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  v = 1234.0; // FP_NORMAL
7002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  for (int i = 0; i < iters; ++i) {
7102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += (isinf)(v);
7202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
7302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
7402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StopBenchmarkTiming();
7502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
7602c78a386739a8a2b3007efeb00a9ca04132100aElliott HughesBENCHMARK(BM_math_isinf_NORMAL);
7702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
7802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughesstatic void BM_math_isinf_NAN(int iters) {
7902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StartBenchmarkTiming();
8002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
8102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
8202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  v = nan(""); // FP_NAN
8302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  for (int i = 0; i < iters; ++i) {
8402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += (isinf)(v);
8502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
8602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
8702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StopBenchmarkTiming();
8802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
8902c78a386739a8a2b3007efeb00a9ca04132100aElliott HughesBENCHMARK(BM_math_isinf_NAN);
9002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
9102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughesstatic void BM_math_isinf_INFINITE(int iters) {
9202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StartBenchmarkTiming();
9302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
9402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
9502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  v = HUGE_VAL; // FP_INFINITE
9602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  for (int i = 0; i < iters; ++i) {
9702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += (isinf)(v);
9802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
9902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
10002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StopBenchmarkTiming();
10102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
10202c78a386739a8a2b3007efeb00a9ca04132100aElliott HughesBENCHMARK(BM_math_isinf_INFINITE);
10302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
10402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughesstatic void BM_math_isinf_ZERO(int iters) {
10502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StartBenchmarkTiming();
10602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
10702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
10802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  v = 0.0; // FP_ZERO
10902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  for (int i = 0; i < iters; ++i) {
11002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += (isinf)(v);
11102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
11202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
11302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StopBenchmarkTiming();
11402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
11502c78a386739a8a2b3007efeb00a9ca04132100aElliott HughesBENCHMARK(BM_math_isinf_ZERO);
11602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
117a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescustatic void BM_math_sin_fast(int iters) {
118a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  StartBenchmarkTiming();
11902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
120a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
121a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  for (int i = 0; i < iters; ++i) {
122a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
123a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
124a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu
125a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  StopBenchmarkTiming();
126a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
127a147a1da5c268e9d556c207be0d3da0a519b2d54Serban ConstantinescuBENCHMARK(BM_math_sin_fast);
12802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
129a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescustatic void BM_math_sin_feupdateenv(int iters) {
130a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  StartBenchmarkTiming();
13102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
132a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
133a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  for (int i = 0; i < iters; ++i) {
134a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fenv_t __libc_save_rm;
135a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feholdexcept(&__libc_save_rm);
136a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetround(FE_TONEAREST);
137a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
138a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feupdateenv(&__libc_save_rm);
139a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
14002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
141a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  StopBenchmarkTiming();
142a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
143a147a1da5c268e9d556c207be0d3da0a519b2d54Serban ConstantinescuBENCHMARK(BM_math_sin_feupdateenv);
144a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu
145a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescustatic void BM_math_sin_fesetenv(int iters) {
146a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  StartBenchmarkTiming();
147a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu
148a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  d = 1.0;
149a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  for (int i = 0; i < iters; ++i) {
150a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fenv_t __libc_save_rm;
151a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    feholdexcept(&__libc_save_rm);
152a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetround(FE_TONEAREST);
153a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    d += sin(d);
154a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu    fesetenv(&__libc_save_rm);
155a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  }
156a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu
157a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu  StopBenchmarkTiming();
158a147a1da5c268e9d556c207be0d3da0a519b2d54Serban Constantinescu}
159a147a1da5c268e9d556c207be0d3da0a519b2d54Serban ConstantinescuBENCHMARK(BM_math_sin_fesetenv);
16002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
16102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughesstatic void BM_math_fpclassify_NORMAL(int iters) {
16202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StartBenchmarkTiming();
16302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
16402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
16502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  v = 1234.0; // FP_NORMAL
16602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  for (int i = 0; i < iters; ++i) {
16702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += fpclassify(v);
16802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
16902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
17002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StopBenchmarkTiming();
17102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
17202c78a386739a8a2b3007efeb00a9ca04132100aElliott HughesBENCHMARK(BM_math_fpclassify_NORMAL);
17302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
17402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughesstatic void BM_math_fpclassify_NAN(int iters) {
17502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StartBenchmarkTiming();
17602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
17702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
17802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  v = nan(""); // FP_NAN
17902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  for (int i = 0; i < iters; ++i) {
18002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += fpclassify(v);
18102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
18202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
18302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StopBenchmarkTiming();
18402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
18502c78a386739a8a2b3007efeb00a9ca04132100aElliott HughesBENCHMARK(BM_math_fpclassify_NAN);
18602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
18702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughesstatic void BM_math_fpclassify_INFINITE(int iters) {
18802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StartBenchmarkTiming();
18902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
19002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
19102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  v = HUGE_VAL; // FP_INFINITE
19202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  for (int i = 0; i < iters; ++i) {
19302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += fpclassify(v);
19402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
19502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
19602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StopBenchmarkTiming();
19702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
19802c78a386739a8a2b3007efeb00a9ca04132100aElliott HughesBENCHMARK(BM_math_fpclassify_INFINITE);
19902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
20002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughesstatic void BM_math_fpclassify_ZERO(int iters) {
20102c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StartBenchmarkTiming();
20202c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
20302c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  d = 0.0;
20402c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  v = 0.0; // FP_ZERO
20502c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  for (int i = 0; i < iters; ++i) {
20602c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes    d += fpclassify(v);
20702c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  }
20802c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes
20902c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes  StopBenchmarkTiming();
21002c78a386739a8a2b3007efeb00a9ca04132100aElliott Hughes}
21102c78a386739a8a2b3007efeb00a9ca04132100aElliott HughesBENCHMARK(BM_math_fpclassify_ZERO);
212