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 27 static void SetLabel(benchmark::State& state) { 28 state.SetLabel(names[state.range(0)]); 29 } 30 31 // Avoid optimization. 32 volatile double d; 33 volatile double v; 34 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 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 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 62 static void BM_math_isfinite_macro(benchmark::State& state) { 63 d = 0.0; 64 v = values[state.range(0)]; 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 77 static void BM_math_isfinite(benchmark::State& state) { 78 d = 0.0; 79 v = values[state.range(0)]; 80 while (state.KeepRunning()) { 81 d += test_isfinite(v); 82 } 83 SetLabel(state); 84 } 85 BENCHMARK_COMMON_VALS(BM_math_isfinite); 86 87 static void BM_math_isinf_macro(benchmark::State& state) { 88 d = 0.0; 89 v = values[state.range(0)]; 90 while (state.KeepRunning()) { 91 d += isinf(v); 92 } 93 SetLabel(state); 94 } 95 BENCHMARK_COMMON_VALS(BM_math_isinf_macro); 96 97 static void BM_math_isinf(benchmark::State& state) { 98 d = 0.0; 99 v = values[state.range(0)]; 100 while (state.KeepRunning()) { 101 d += (isinf)(v); 102 } 103 SetLabel(state); 104 } 105 BENCHMARK_COMMON_VALS(BM_math_isinf); 106 107 static void BM_math_isnan_macro(benchmark::State& state) { 108 d = 0.0; 109 v = values[state.range(0)]; 110 while (state.KeepRunning()) { 111 d += isnan(v); 112 } 113 SetLabel(state); 114 } 115 BENCHMARK_COMMON_VALS(BM_math_isnan_macro); 116 117 static void BM_math_isnan(benchmark::State& state) { 118 d = 0.0; 119 v = values[state.range(0)]; 120 while (state.KeepRunning()) { 121 d += (isnan)(v); 122 } 123 SetLabel(state); 124 } 125 BENCHMARK_COMMON_VALS(BM_math_isnan); 126 127 static void BM_math_isnormal_macro(benchmark::State& state) { 128 d = 0.0; 129 v = values[state.range(0)]; 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__) 138 static void BM_math_isnormal(benchmark::State& state) { 139 d = 0.0; 140 v = values[state.range(0)]; 141 while (state.KeepRunning()) { 142 d += (__isnormal)(v); 143 } 144 SetLabel(state); 145 } 146 BENCHMARK_COMMON_VALS(BM_math_isnormal); 147 #endif 148 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 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 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 181 static void BM_math_fpclassify(benchmark::State& state) { 182 d = 0.0; 183 v = values[state.range(0)]; 184 while (state.KeepRunning()) { 185 d += fpclassify(v); 186 } 187 SetLabel(state); 188 } 189 BENCHMARK_COMMON_VALS(BM_math_fpclassify); 190 191 static void BM_math_signbit_macro(benchmark::State& state) { 192 d = 0.0; 193 v = values[state.range(0)]; 194 while (state.KeepRunning()) { 195 d += signbit(v); 196 } 197 SetLabel(state); 198 } 199 BENCHMARK_COMMON_VALS(BM_math_signbit_macro); 200 201 static void BM_math_signbit(benchmark::State& state) { 202 d = 0.0; 203 v = values[state.range(0)]; 204 while (state.KeepRunning()) { 205 d += (__signbit)(v); 206 } 207 SetLabel(state); 208 } 209 BENCHMARK_COMMON_VALS(BM_math_signbit); 210 211 static void BM_math_fabs_macro(benchmark::State& state) { 212 d = 0.0; 213 v = values[state.range(0)]; 214 while (state.KeepRunning()) { 215 d += fabs(v); 216 } 217 SetLabel(state); 218 } 219 BENCHMARK_COMMON_VALS(BM_math_fabs_macro); 220 221 static void BM_math_fabs(benchmark::State& state) { 222 d = 0.0; 223 v = values[state.range(0)]; 224 while (state.KeepRunning()) { 225 d += (fabs)(v); 226 } 227 SetLabel(state); 228 } 229 BENCHMARK_COMMON_VALS(BM_math_fabs); 230