Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / go / math / big / calibrate_test.go
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 }