The Go Programming Language

Source file src/pkg/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: gotest -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	// measure returns the time to run f
    25	func measure(f func()) int64 {
    26		const N = 100
    27		start := time.Nanoseconds()
    28		for i := N; i > 0; i-- {
    29			f()
    30		}
    31		stop := time.Nanoseconds()
    32		return (stop - start) / N
    33	}
    34	
    35	func computeThresholds() {
    36		fmt.Printf("Multiplication times for varying Karatsuba thresholds\n")
    37		fmt.Printf("(run repeatedly for good results)\n")
    38	
    39		// determine Tk, the work load execution time using basic multiplication
    40		karatsubaThreshold = 1e9 // disable karatsuba
    41		Tb := measure(benchmarkMulLoad)
    42		fmt.Printf("Tb = %dns\n", Tb)
    43	
    44		// thresholds
    45		n := 8 // any lower values for the threshold lead to very slow multiplies
    46		th1 := -1
    47		th2 := -1
    48	
    49		var deltaOld int64
    50		for count := -1; count != 0; count-- {
    51			// determine Tk, the work load execution time using Karatsuba multiplication
    52			karatsubaThreshold = n // enable karatsuba
    53			Tk := measure(benchmarkMulLoad)
    54	
    55			// improvement over Tb
    56			delta := (Tb - Tk) * 100 / Tb
    57	
    58			fmt.Printf("n = %3d  Tk = %8dns  %4d%%", n, Tk, delta)
    59	
    60			// determine break-even point
    61			if Tk < Tb && th1 < 0 {
    62				th1 = n
    63				fmt.Print("  break-even point")
    64			}
    65	
    66			// determine diminishing return
    67			if 0 < delta && delta < deltaOld && th2 < 0 {
    68				th2 = n
    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 = 20 // this many extra measurements after we got both thresholds
    78			}
    79	
    80			n++
    81		}
    82	}
    83	
    84	func TestCalibrate(t *testing.T) {
    85		if *calibrate {
    86			computeThresholds()
    87		}
    88	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.