From 6cfc3b25e95d9f41215e0df8eadfdbeb472594fe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20M=C3=B6hrmann?= Date: Sat, 18 Feb 2017 09:32:46 +0100 Subject: [PATCH] math: protect benchmarked functions from being optimized away Add exported global variables and store the results of benchmarked functions in them. This prevents the current compiler optimizations from removing the instructions that are needed to compute the return values of the benchmarked functions. Change-Id: If8b08424e85f3796bb6dd73e761c653abbabcc5e Reviewed-on: https://go-review.googlesource.com/37195 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/math/all_test.go | 271 +++++++++++++++++++++++++++++++------------ 1 file changed, 200 insertions(+), 71 deletions(-) diff --git a/src/math/all_test.go b/src/math/all_test.go index 3328904aa7..df770a1fe0 100644 --- a/src/math/all_test.go +++ b/src/math/all_test.go @@ -2794,327 +2794,448 @@ func TestFloatMinMax(t *testing.T) { // Benchmarks +// Global exported variables are used to store the +// return values of functions measured in the benchmarks. +// Storing the results in these variables prevents the compiler +// from completely optimizing the benchmarked functions away. +var ( + GlobalI int + GlobalB bool + GlobalF float64 +) + func BenchmarkAcos(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Acos(.5) + x = Acos(.5) } + GlobalF = x } func BenchmarkAcosh(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Acosh(1.5) + x = Acosh(1.5) } + GlobalF = x } func BenchmarkAsin(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Asin(.5) + x = Asin(.5) } + GlobalF = x } func BenchmarkAsinh(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Asinh(.5) + x = Asinh(.5) } + GlobalF = x } func BenchmarkAtan(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Atan(.5) + x = Atan(.5) } + GlobalF = x } func BenchmarkAtanh(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Atanh(.5) + x = Atanh(.5) } + GlobalF = x } func BenchmarkAtan2(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Atan2(.5, 1) + x = Atan2(.5, 1) } + GlobalF = x } func BenchmarkCbrt(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Cbrt(10) + x = Cbrt(10) } + GlobalF = x } func BenchmarkCeil(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Ceil(.5) + x = Ceil(.5) } + GlobalF = x } func BenchmarkCopysign(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Copysign(.5, -1) + x = Copysign(.5, -1) } + GlobalF = x } func BenchmarkCos(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Cos(.5) + x = Cos(.5) } + GlobalF = x } func BenchmarkCosh(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Cosh(2.5) + x = Cosh(2.5) } + GlobalF = x } func BenchmarkErf(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Erf(.5) + x = Erf(.5) } + GlobalF = x } func BenchmarkErfc(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Erfc(.5) + x = Erfc(.5) } + GlobalF = x } func BenchmarkExp(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Exp(.5) + x = Exp(.5) } + GlobalF = x } func BenchmarkExpGo(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - ExpGo(.5) + x = ExpGo(.5) } + GlobalF = x } func BenchmarkExpm1(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Expm1(.5) + x = Expm1(.5) } + GlobalF = x } func BenchmarkExp2(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Exp2(.5) + x = Exp2(.5) } + GlobalF = x } func BenchmarkExp2Go(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Exp2Go(.5) + x = Exp2Go(.5) } + GlobalF = x } func BenchmarkAbs(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Abs(.5) + x = Abs(.5) } + GlobalF = x + } func BenchmarkDim(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Dim(10, 3) + x = Dim(10, 3) } + GlobalF = x } func BenchmarkFloor(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Floor(.5) + x = Floor(.5) } + GlobalF = x } func BenchmarkMax(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Max(10, 3) + x = Max(10, 3) } + GlobalF = x } func BenchmarkMin(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Min(10, 3) + x = Min(10, 3) } + GlobalF = x } func BenchmarkMod(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Mod(10, 3) + x = Mod(10, 3) } + GlobalF = x } func BenchmarkFrexp(b *testing.B) { + x := 0.0 + y := 0 for i := 0; i < b.N; i++ { - Frexp(8) + x, y = Frexp(8) } + GlobalF = x + GlobalI = y } func BenchmarkGamma(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Gamma(2.5) + x = Gamma(2.5) } + GlobalF = x } func BenchmarkHypot(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Hypot(3, 4) + x = Hypot(3, 4) } + GlobalF = x } func BenchmarkHypotGo(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - HypotGo(3, 4) + x = HypotGo(3, 4) } + GlobalF = x } func BenchmarkIlogb(b *testing.B) { + x := 0 for i := 0; i < b.N; i++ { - Ilogb(.5) + x = Ilogb(.5) } + GlobalI = x } func BenchmarkJ0(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - J0(2.5) + x = J0(2.5) } + GlobalF = x } func BenchmarkJ1(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - J1(2.5) + x = J1(2.5) } + GlobalF = x } func BenchmarkJn(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Jn(2, 2.5) + x = Jn(2, 2.5) } + GlobalF = x } func BenchmarkLdexp(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Ldexp(.5, 2) + x = Ldexp(.5, 2) } + GlobalF = x } func BenchmarkLgamma(b *testing.B) { + x := 0.0 + y := 0 for i := 0; i < b.N; i++ { - Lgamma(2.5) + x, y = Lgamma(2.5) } + GlobalF = x + GlobalI = y } func BenchmarkLog(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Log(.5) + x = Log(.5) } + GlobalF = x } func BenchmarkLogb(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Logb(.5) + x = Logb(.5) } + GlobalF = x } func BenchmarkLog1p(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Log1p(.5) + x = Log1p(.5) } + GlobalF = x } func BenchmarkLog10(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Log10(.5) + x = Log10(.5) } + GlobalF = x } func BenchmarkLog2(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Log2(.5) + x = Log2(.5) } + GlobalF += x } func BenchmarkModf(b *testing.B) { + x := 0.0 + y := 0.0 for i := 0; i < b.N; i++ { - Modf(1.5) + x, y = Modf(1.5) } + GlobalF += x + GlobalF += y } func BenchmarkNextafter32(b *testing.B) { + x := float32(0.0) for i := 0; i < b.N; i++ { - Nextafter32(.5, 1) + x = Nextafter32(.5, 1) } + GlobalF = float64(x) } func BenchmarkNextafter64(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Nextafter(.5, 1) + x = Nextafter(.5, 1) } + GlobalF = x } func BenchmarkPowInt(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Pow(2, 2) + x = Pow(2, 2) } + GlobalF = x } func BenchmarkPowFrac(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Pow(2.5, 1.5) + x = Pow(2.5, 1.5) } + GlobalF = x } func BenchmarkPow10Pos(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Pow10(300) + x = Pow10(300) } + GlobalF = x } func BenchmarkPow10Neg(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Pow10(-300) + x = Pow10(-300) } + GlobalF = x } func BenchmarkRemainder(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Remainder(10, 3) + x = Remainder(10, 3) } + GlobalF = x } func BenchmarkSignbit(b *testing.B) { + x := false for i := 0; i < b.N; i++ { - Signbit(2.5) + x = Signbit(2.5) } + GlobalB = x } func BenchmarkSin(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Sin(.5) + x = Sin(.5) } + GlobalF = x } func BenchmarkSincos(b *testing.B) { + x := 0.0 + y := 0.0 for i := 0; i < b.N; i++ { - Sincos(.5) + x, y = Sincos(.5) } + GlobalF += x + GlobalF += y } func BenchmarkSinh(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Sinh(2.5) + x = Sinh(2.5) } + GlobalF = x } -var Global float64 - func BenchmarkSqrtIndirect(b *testing.B) { x, y := 0.0, 10.0 f := Sqrt for i := 0; i < b.N; i++ { x += f(y) } - Global = x + GlobalF = x } func BenchmarkSqrtLatency(b *testing.B) { @@ -3122,7 +3243,7 @@ func BenchmarkSqrtLatency(b *testing.B) { for i := 0; i < b.N; i++ { x = Sqrt(x) } - Global = x + GlobalF = x } func BenchmarkSqrtIndirectLatency(b *testing.B) { @@ -3131,7 +3252,7 @@ func BenchmarkSqrtIndirectLatency(b *testing.B) { for i := 0; i < b.N; i++ { x = f(x) } - Global = x + GlobalF = x } func BenchmarkSqrtGoLatency(b *testing.B) { @@ -3139,7 +3260,7 @@ func BenchmarkSqrtGoLatency(b *testing.B) { for i := 0; i < b.N; i++ { x = SqrtGo(x) } - Global = x + GlobalF = x } func isPrime(i int) bool { @@ -3157,48 +3278,56 @@ func isPrime(i int) bool { } func BenchmarkSqrtPrime(b *testing.B) { - any := false + x := false for i := 0; i < b.N; i++ { - if isPrime(100003) { - any = true - } - } - if any { - Global = 1 + x = isPrime(100003) } + GlobalB = x } func BenchmarkTan(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Tan(.5) + x = Tan(.5) } + GlobalF = x } func BenchmarkTanh(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Tanh(2.5) + x = Tanh(2.5) } + GlobalF = x } func BenchmarkTrunc(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Trunc(.5) + x = Trunc(.5) } + GlobalF = x } func BenchmarkY0(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Y0(2.5) + x = Y0(2.5) } + GlobalF = x } func BenchmarkY1(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Y1(2.5) + x = Y1(2.5) } + GlobalF = x } func BenchmarkYn(b *testing.B) { + x := 0.0 for i := 0; i < b.N; i++ { - Yn(2, 2.5) + x = Yn(2, 2.5) } + GlobalF = x } -- 2.48.1