github.com/flyinox/gosm@v0.0.0-20171117061539-16768cb62077/src/math/big/calibrate_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file prints execution times for the Mul benchmark 6 // given different Karatsuba thresholds. The result may be 7 // used to manually fine-tune the threshold constant. The 8 // results are somewhat fragile; use repeated runs to get 9 // a clear picture. 10 11 // Usage: go test -run=TestCalibrate -calibrate 12 13 package big 14 15 import ( 16 "flag" 17 "fmt" 18 "testing" 19 "time" 20 ) 21 22 var calibrate = flag.Bool("calibrate", false, "run calibration test") 23 24 func karatsubaLoad(b *testing.B) { 25 BenchmarkMul(b) 26 } 27 28 // measureKaratsuba returns the time to run a Karatsuba-relevant benchmark 29 // given Karatsuba threshold th. 30 func measureKaratsuba(th int) time.Duration { 31 th, karatsubaThreshold = karatsubaThreshold, th 32 res := testing.Benchmark(karatsubaLoad) 33 karatsubaThreshold = th 34 return time.Duration(res.NsPerOp()) 35 } 36 37 func computeThresholds() { 38 fmt.Printf("Multiplication times for varying Karatsuba thresholds\n") 39 fmt.Printf("(run repeatedly for good results)\n") 40 41 // determine Tk, the work load execution time using basic multiplication 42 Tb := measureKaratsuba(1e9) // th == 1e9 => Karatsuba multiplication disabled 43 fmt.Printf("Tb = %10s\n", Tb) 44 45 // thresholds 46 th := 4 47 th1 := -1 48 th2 := -1 49 50 var deltaOld time.Duration 51 for count := -1; count != 0 && th < 128; count-- { 52 // determine Tk, the work load execution time using Karatsuba multiplication 53 Tk := measureKaratsuba(th) 54 55 // improvement over Tb 56 delta := (Tb - Tk) * 100 / Tb 57 58 fmt.Printf("th = %3d Tk = %10s %4d%%", th, Tk, delta) 59 60 // determine break-even point 61 if Tk < Tb && th1 < 0 { 62 th1 = th 63 fmt.Print(" break-even point") 64 } 65 66 // determine diminishing return 67 if 0 < delta && delta < deltaOld && th2 < 0 { 68 th2 = th 69 fmt.Print(" diminishing return") 70 } 71 deltaOld = delta 72 73 fmt.Println() 74 75 // trigger counter 76 if th1 >= 0 && th2 >= 0 && count < 0 { 77 count = 10 // this many extra measurements after we got both thresholds 78 } 79 80 th++ 81 } 82 } 83 84 func TestCalibrate(t *testing.T) { 85 if *calibrate { 86 computeThresholds() 87 } 88 }