github.com/gopherd/gonum@v0.0.4/internal/asm/f64/benchAxpy_test.go (about)

     1  // Copyright ©2017 The Gonum 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  package f64_test
     6  
     7  import (
     8  	"fmt"
     9  	"testing"
    10  
    11  	. "github.com/gopherd/gonum/internal/asm/f64"
    12  )
    13  
    14  const testLen = 1e5
    15  
    16  var (
    17  	a = 2.0
    18  	x = make([]float64, testLen)
    19  	y = make([]float64, testLen)
    20  	z = make([]float64, testLen)
    21  )
    22  
    23  func init() {
    24  	for n := range x {
    25  		x[n] = float64(n)
    26  		y[n] = float64(n)
    27  	}
    28  }
    29  
    30  func BenchmarkAxpyUnitary(t *testing.B) {
    31  	naiveaxpyu := func(a float64, x, y []float64) {
    32  		for i, v := range x {
    33  			y[i] += a * v
    34  		}
    35  	}
    36  	tests := []struct {
    37  		name string
    38  		f    func(a float64, x, y []float64)
    39  	}{
    40  		{"AxpyUnitary", AxpyUnitary},
    41  		{"NaiveAxpyUnitary", naiveaxpyu},
    42  	}
    43  	for _, test := range tests {
    44  		for _, ln := range []uintptr{1, 3, 10, 30, 1e2, 3e2, 1e3, 3e3, 1e4, 3e4, 1e5} {
    45  			t.Run(fmt.Sprintf("%s-%d", test.name, ln), func(b *testing.B) {
    46  				b.SetBytes(int64(64 * ln))
    47  				x, y := x[:ln], y[:ln]
    48  				b.ResetTimer()
    49  				for i := 0; i < b.N; i++ {
    50  					test.f(a, x, y)
    51  				}
    52  			})
    53  		}
    54  	}
    55  }
    56  
    57  func BenchmarkAxpyUnitaryTo(t *testing.B) {
    58  	naiveaxpyut := func(d []float64, a float64, x, y []float64) {
    59  		for i, v := range x {
    60  			d[i] = y[i] + a*v
    61  		}
    62  	}
    63  	tests := []struct {
    64  		name string
    65  		f    func(z []float64, a float64, x, y []float64)
    66  	}{
    67  		{"AxpyUnitaryTo", AxpyUnitaryTo},
    68  		{"NaiveAxpyUnitaryTo", naiveaxpyut},
    69  	}
    70  	for _, test := range tests {
    71  		for _, ln := range []uintptr{1, 3, 10, 30, 1e2, 3e2, 1e3, 3e3, 1e4, 3e4, 1e5} {
    72  			t.Run(fmt.Sprintf("%s-%d", test.name, ln), func(b *testing.B) {
    73  				b.SetBytes(int64(64 * ln))
    74  				x, y, z := x[:ln], y[:ln], z[:ln]
    75  				b.ResetTimer()
    76  				for i := 0; i < b.N; i++ {
    77  					test.f(z, a, x, y)
    78  				}
    79  			})
    80  		}
    81  	}
    82  }
    83  
    84  var incsAxpy = []struct {
    85  	len uintptr
    86  	inc []int
    87  }{
    88  	{1, []int{1}},
    89  	{2, []int{1, 2, 4, 10}},
    90  	{3, []int{1, 2, 4, 10}},
    91  	{4, []int{1, 2, 4, 10}},
    92  	{5, []int{1, 2, 4, 10}},
    93  	{10, []int{1, 2, 4, 10}},
    94  	{500, []int{1, 2, 4, 10}},
    95  	{1e3, []int{1, 2, 4, 10}},
    96  	{1e4, []int{1, 2, 4, 10, -1, -2, -4, -10}},
    97  }
    98  
    99  func BenchmarkAxpyInc(t *testing.B) {
   100  	naiveaxpyinc := func(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) {
   101  		for i := 0; i < int(n); i++ {
   102  			y[iy] += alpha * x[ix]
   103  			ix += incX
   104  			iy += incY
   105  		}
   106  	}
   107  	tests := []struct {
   108  		name string
   109  		f    func(alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr)
   110  	}{
   111  		{"AxpyInc", AxpyInc},
   112  		{"NaiveAxpyInc", naiveaxpyinc},
   113  	}
   114  	for _, test := range tests {
   115  		for _, tt := range incsAxpy {
   116  			for _, inc := range tt.inc {
   117  				t.Run(fmt.Sprintf("%s-%d-inc(%d)", test.name, tt.len, inc), func(b *testing.B) {
   118  					b.SetBytes(int64(64 * tt.len))
   119  					var idx, tstInc uintptr = 0, uintptr(inc)
   120  					if inc < 0 {
   121  						idx = uintptr((-int(tt.len) + 1) * inc)
   122  					}
   123  					for i := 0; i < b.N; i++ {
   124  						test.f(a, x, y, uintptr(tt.len), tstInc, tstInc, idx, idx)
   125  					}
   126  				})
   127  			}
   128  		}
   129  	}
   130  }
   131  
   132  func BenchmarkAxpyIncTo(t *testing.B) {
   133  	naiveaxpyincto := func(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr) {
   134  		for i := 0; i < int(n); i++ {
   135  			dst[idst] = alpha*x[ix] + y[iy]
   136  			ix += incX
   137  			iy += incY
   138  			idst += incDst
   139  		}
   140  	}
   141  	tests := []struct {
   142  		name string
   143  		f    func(dst []float64, incDst, idst uintptr, alpha float64, x, y []float64, n, incX, incY, ix, iy uintptr)
   144  	}{
   145  		{"AxpyIncTo", AxpyIncTo},
   146  		{"NaiveAxpyIncTo", naiveaxpyincto},
   147  	}
   148  	for _, test := range tests {
   149  		for _, tt := range incsAxpy {
   150  			for _, inc := range tt.inc {
   151  				t.Run(fmt.Sprintf("%s-%d-inc(%d)", test.name, tt.len, inc), func(b *testing.B) {
   152  					b.SetBytes(int64(64 * tt.len))
   153  					var idx, tstInc uintptr = 0, uintptr(inc)
   154  					if inc < 0 {
   155  						idx = uintptr((-int(tt.len) + 1) * inc)
   156  					}
   157  					for i := 0; i < b.N; i++ {
   158  						test.f(z, tstInc, idx, a, x, y, uintptr(tt.len),
   159  							tstInc, tstInc, idx, idx)
   160  					}
   161  				})
   162  			}
   163  		}
   164  	}
   165  }