github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/bench/dot/main_test.go (about) 1 package main 2 3 import ( 4 "testing" 5 "unsafe" 6 ) 7 8 func Dot1(a, b []float64) float64 { 9 var sum float64 10 for i := 0; i < len(a); i += 4 { 11 s0 := a[i] * b[i] 12 s1 := a[i+1] * b[i+1] 13 s2 := a[i+2] * b[i+2] 14 s3 := a[i+3] * b[i+3] 15 sum += s0 + s1 + s2 + s3 16 } 17 return sum 18 } 19 20 func Dot2(a, b []float64) float64 { 21 type F64x4 struct{ X, Y, Z, W float64 } 22 23 xs := unsafe.Slice((*F64x4)(unsafe.Pointer(unsafe.SliceData(a))), len(a)/4) 24 ys := unsafe.Slice((*F64x4)(unsafe.Pointer(unsafe.SliceData(b))), len(b)/4) 25 26 if len(xs) != len(ys) { 27 return 0 28 } 29 30 var x, y, z, w float64 31 32 for i := range xs { 33 x += xs[i].X * ys[i].X 34 y += xs[i].Y * ys[i].Y 35 z += xs[i].Z * ys[i].Z 36 w += xs[i].W * ys[i].W 37 } 38 39 // TODO: handle leftover stuff 40 41 return x + y + z + w 42 } 43 44 func Dot3(a, b []float64) float64 { 45 var x, y, z, w float64 46 47 for i := 0; i < len(a); i += 4 { 48 x += a[i] * b[i] 49 y += a[i+1] * b[i+1] 50 z += a[i+2] * b[i+2] 51 w += a[i+3] * b[i+3] 52 } 53 54 return x + y + z + w 55 } 56 57 func Dot4(a, b []float64) float64 { 58 var sum float64 59 60 for len(a) >= 4 && len(b) >= 4 { 61 s0 := a[0] * b[0] 62 s1 := a[1] * b[1] 63 s2 := a[2] * b[2] 64 s3 := a[3] * b[3] 65 sum += s0 + s1 + s2 + s3 66 a = a[4:] 67 b = b[4:] 68 } 69 // deal with remainder of a and b 70 return sum 71 } 72 73 func Dot5(a, b []float64) float64 { 74 var x, y, z, w float64 75 76 for len(a) >= 4 && len(b) >= 4 { 77 x += a[0] * b[0] 78 y += a[1] * b[1] 79 z += a[2] * b[2] 80 w += a[3] * b[3] 81 a, b = a[4:], b[4:] 82 } 83 84 return x + y + z + w 85 } 86 87 var ( 88 xs = make([]float64, 10*1024) 89 ys = make([]float64, 10*1024) 90 91 sink float64 92 ) 93 94 func BenchmarkDot1(b *testing.B) { 95 for i := 0; i < b.N; i++ { 96 sink += Dot1(xs, ys) 97 } 98 } 99 100 func BenchmarkDot2(b *testing.B) { 101 for i := 0; i < b.N; i++ { 102 sink += Dot2(xs, ys) 103 } 104 } 105 106 func BenchmarkDot3(b *testing.B) { 107 for i := 0; i < b.N; i++ { 108 sink += Dot3(xs, ys) 109 } 110 } 111 112 func BenchmarkDot4(b *testing.B) { 113 for i := 0; i < b.N; i++ { 114 sink += Dot4(xs, ys) 115 } 116 } 117 118 func BenchmarkDot5(b *testing.B) { 119 for i := 0; i < b.N; i++ { 120 sink += Dot5(xs, ys) 121 } 122 }