Commit 6cfc3b25 authored by Martin Möhrmann's avatar Martin Möhrmann

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/37195Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 6ef92b6e
...@@ -2794,327 +2794,448 @@ func TestFloatMinMax(t *testing.T) { ...@@ -2794,327 +2794,448 @@ func TestFloatMinMax(t *testing.T) {
// Benchmarks // 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) { func BenchmarkAcos(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Acos(.5) x = Acos(.5)
} }
GlobalF = x
} }
func BenchmarkAcosh(b *testing.B) { func BenchmarkAcosh(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Acosh(1.5) x = Acosh(1.5)
} }
GlobalF = x
} }
func BenchmarkAsin(b *testing.B) { func BenchmarkAsin(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Asin(.5) x = Asin(.5)
} }
GlobalF = x
} }
func BenchmarkAsinh(b *testing.B) { func BenchmarkAsinh(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Asinh(.5) x = Asinh(.5)
} }
GlobalF = x
} }
func BenchmarkAtan(b *testing.B) { func BenchmarkAtan(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Atan(.5) x = Atan(.5)
} }
GlobalF = x
} }
func BenchmarkAtanh(b *testing.B) { func BenchmarkAtanh(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Atanh(.5) x = Atanh(.5)
} }
GlobalF = x
} }
func BenchmarkAtan2(b *testing.B) { func BenchmarkAtan2(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Atan2(.5, 1) x = Atan2(.5, 1)
} }
GlobalF = x
} }
func BenchmarkCbrt(b *testing.B) { func BenchmarkCbrt(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Cbrt(10) x = Cbrt(10)
} }
GlobalF = x
} }
func BenchmarkCeil(b *testing.B) { func BenchmarkCeil(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Ceil(.5) x = Ceil(.5)
} }
GlobalF = x
} }
func BenchmarkCopysign(b *testing.B) { func BenchmarkCopysign(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Copysign(.5, -1) x = Copysign(.5, -1)
} }
GlobalF = x
} }
func BenchmarkCos(b *testing.B) { func BenchmarkCos(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Cos(.5) x = Cos(.5)
} }
GlobalF = x
} }
func BenchmarkCosh(b *testing.B) { func BenchmarkCosh(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Cosh(2.5) x = Cosh(2.5)
} }
GlobalF = x
} }
func BenchmarkErf(b *testing.B) { func BenchmarkErf(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Erf(.5) x = Erf(.5)
} }
GlobalF = x
} }
func BenchmarkErfc(b *testing.B) { func BenchmarkErfc(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Erfc(.5) x = Erfc(.5)
} }
GlobalF = x
} }
func BenchmarkExp(b *testing.B) { func BenchmarkExp(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Exp(.5) x = Exp(.5)
} }
GlobalF = x
} }
func BenchmarkExpGo(b *testing.B) { func BenchmarkExpGo(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
ExpGo(.5) x = ExpGo(.5)
} }
GlobalF = x
} }
func BenchmarkExpm1(b *testing.B) { func BenchmarkExpm1(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Expm1(.5) x = Expm1(.5)
} }
GlobalF = x
} }
func BenchmarkExp2(b *testing.B) { func BenchmarkExp2(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Exp2(.5) x = Exp2(.5)
} }
GlobalF = x
} }
func BenchmarkExp2Go(b *testing.B) { func BenchmarkExp2Go(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Exp2Go(.5) x = Exp2Go(.5)
} }
GlobalF = x
} }
func BenchmarkAbs(b *testing.B) { func BenchmarkAbs(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Abs(.5) x = Abs(.5)
} }
GlobalF = x
} }
func BenchmarkDim(b *testing.B) { func BenchmarkDim(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Dim(10, 3) x = Dim(10, 3)
} }
GlobalF = x
} }
func BenchmarkFloor(b *testing.B) { func BenchmarkFloor(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Floor(.5) x = Floor(.5)
} }
GlobalF = x
} }
func BenchmarkMax(b *testing.B) { func BenchmarkMax(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Max(10, 3) x = Max(10, 3)
} }
GlobalF = x
} }
func BenchmarkMin(b *testing.B) { func BenchmarkMin(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Min(10, 3) x = Min(10, 3)
} }
GlobalF = x
} }
func BenchmarkMod(b *testing.B) { func BenchmarkMod(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Mod(10, 3) x = Mod(10, 3)
} }
GlobalF = x
} }
func BenchmarkFrexp(b *testing.B) { func BenchmarkFrexp(b *testing.B) {
x := 0.0
y := 0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Frexp(8) x, y = Frexp(8)
} }
GlobalF = x
GlobalI = y
} }
func BenchmarkGamma(b *testing.B) { func BenchmarkGamma(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Gamma(2.5) x = Gamma(2.5)
} }
GlobalF = x
} }
func BenchmarkHypot(b *testing.B) { func BenchmarkHypot(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Hypot(3, 4) x = Hypot(3, 4)
} }
GlobalF = x
} }
func BenchmarkHypotGo(b *testing.B) { func BenchmarkHypotGo(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
HypotGo(3, 4) x = HypotGo(3, 4)
} }
GlobalF = x
} }
func BenchmarkIlogb(b *testing.B) { func BenchmarkIlogb(b *testing.B) {
x := 0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Ilogb(.5) x = Ilogb(.5)
} }
GlobalI = x
} }
func BenchmarkJ0(b *testing.B) { func BenchmarkJ0(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
J0(2.5) x = J0(2.5)
} }
GlobalF = x
} }
func BenchmarkJ1(b *testing.B) { func BenchmarkJ1(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
J1(2.5) x = J1(2.5)
} }
GlobalF = x
} }
func BenchmarkJn(b *testing.B) { func BenchmarkJn(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Jn(2, 2.5) x = Jn(2, 2.5)
} }
GlobalF = x
} }
func BenchmarkLdexp(b *testing.B) { func BenchmarkLdexp(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Ldexp(.5, 2) x = Ldexp(.5, 2)
} }
GlobalF = x
} }
func BenchmarkLgamma(b *testing.B) { func BenchmarkLgamma(b *testing.B) {
x := 0.0
y := 0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Lgamma(2.5) x, y = Lgamma(2.5)
} }
GlobalF = x
GlobalI = y
} }
func BenchmarkLog(b *testing.B) { func BenchmarkLog(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Log(.5) x = Log(.5)
} }
GlobalF = x
} }
func BenchmarkLogb(b *testing.B) { func BenchmarkLogb(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Logb(.5) x = Logb(.5)
} }
GlobalF = x
} }
func BenchmarkLog1p(b *testing.B) { func BenchmarkLog1p(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Log1p(.5) x = Log1p(.5)
} }
GlobalF = x
} }
func BenchmarkLog10(b *testing.B) { func BenchmarkLog10(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Log10(.5) x = Log10(.5)
} }
GlobalF = x
} }
func BenchmarkLog2(b *testing.B) { func BenchmarkLog2(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Log2(.5) x = Log2(.5)
} }
GlobalF += x
} }
func BenchmarkModf(b *testing.B) { func BenchmarkModf(b *testing.B) {
x := 0.0
y := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Modf(1.5) x, y = Modf(1.5)
} }
GlobalF += x
GlobalF += y
} }
func BenchmarkNextafter32(b *testing.B) { func BenchmarkNextafter32(b *testing.B) {
x := float32(0.0)
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Nextafter32(.5, 1) x = Nextafter32(.5, 1)
} }
GlobalF = float64(x)
} }
func BenchmarkNextafter64(b *testing.B) { func BenchmarkNextafter64(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Nextafter(.5, 1) x = Nextafter(.5, 1)
} }
GlobalF = x
} }
func BenchmarkPowInt(b *testing.B) { func BenchmarkPowInt(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Pow(2, 2) x = Pow(2, 2)
} }
GlobalF = x
} }
func BenchmarkPowFrac(b *testing.B) { func BenchmarkPowFrac(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { 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) { func BenchmarkPow10Pos(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Pow10(300) x = Pow10(300)
} }
GlobalF = x
} }
func BenchmarkPow10Neg(b *testing.B) { func BenchmarkPow10Neg(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Pow10(-300) x = Pow10(-300)
} }
GlobalF = x
} }
func BenchmarkRemainder(b *testing.B) { func BenchmarkRemainder(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Remainder(10, 3) x = Remainder(10, 3)
} }
GlobalF = x
} }
func BenchmarkSignbit(b *testing.B) { func BenchmarkSignbit(b *testing.B) {
x := false
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Signbit(2.5) x = Signbit(2.5)
} }
GlobalB = x
} }
func BenchmarkSin(b *testing.B) { func BenchmarkSin(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Sin(.5) x = Sin(.5)
} }
GlobalF = x
} }
func BenchmarkSincos(b *testing.B) { func BenchmarkSincos(b *testing.B) {
x := 0.0
y := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Sincos(.5) x, y = Sincos(.5)
} }
GlobalF += x
GlobalF += y
} }
func BenchmarkSinh(b *testing.B) { func BenchmarkSinh(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Sinh(2.5) x = Sinh(2.5)
} }
GlobalF = x
} }
var Global float64
func BenchmarkSqrtIndirect(b *testing.B) { func BenchmarkSqrtIndirect(b *testing.B) {
x, y := 0.0, 10.0 x, y := 0.0, 10.0
f := Sqrt f := Sqrt
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
x += f(y) x += f(y)
} }
Global = x GlobalF = x
} }
func BenchmarkSqrtLatency(b *testing.B) { func BenchmarkSqrtLatency(b *testing.B) {
...@@ -3122,7 +3243,7 @@ func BenchmarkSqrtLatency(b *testing.B) { ...@@ -3122,7 +3243,7 @@ func BenchmarkSqrtLatency(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
x = Sqrt(x) x = Sqrt(x)
} }
Global = x GlobalF = x
} }
func BenchmarkSqrtIndirectLatency(b *testing.B) { func BenchmarkSqrtIndirectLatency(b *testing.B) {
...@@ -3131,7 +3252,7 @@ func BenchmarkSqrtIndirectLatency(b *testing.B) { ...@@ -3131,7 +3252,7 @@ func BenchmarkSqrtIndirectLatency(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
x = f(x) x = f(x)
} }
Global = x GlobalF = x
} }
func BenchmarkSqrtGoLatency(b *testing.B) { func BenchmarkSqrtGoLatency(b *testing.B) {
...@@ -3139,7 +3260,7 @@ func BenchmarkSqrtGoLatency(b *testing.B) { ...@@ -3139,7 +3260,7 @@ func BenchmarkSqrtGoLatency(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
x = SqrtGo(x) x = SqrtGo(x)
} }
Global = x GlobalF = x
} }
func isPrime(i int) bool { func isPrime(i int) bool {
...@@ -3157,48 +3278,56 @@ func isPrime(i int) bool { ...@@ -3157,48 +3278,56 @@ func isPrime(i int) bool {
} }
func BenchmarkSqrtPrime(b *testing.B) { func BenchmarkSqrtPrime(b *testing.B) {
any := false x := false
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
if isPrime(100003) { x = isPrime(100003)
any = true
}
}
if any {
Global = 1
} }
GlobalB = x
} }
func BenchmarkTan(b *testing.B) { func BenchmarkTan(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Tan(.5) x = Tan(.5)
} }
GlobalF = x
} }
func BenchmarkTanh(b *testing.B) { func BenchmarkTanh(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Tanh(2.5) x = Tanh(2.5)
} }
GlobalF = x
} }
func BenchmarkTrunc(b *testing.B) { func BenchmarkTrunc(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Trunc(.5) x = Trunc(.5)
} }
GlobalF = x
} }
func BenchmarkY0(b *testing.B) { func BenchmarkY0(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Y0(2.5) x = Y0(2.5)
} }
GlobalF = x
} }
func BenchmarkY1(b *testing.B) { func BenchmarkY1(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Y1(2.5) x = Y1(2.5)
} }
GlobalF = x
} }
func BenchmarkYn(b *testing.B) { func BenchmarkYn(b *testing.B) {
x := 0.0
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Yn(2, 2.5) x = Yn(2, 2.5)
} }
GlobalF = x
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment