/
bunch.go
74 lines (65 loc) · 1.42 KB
/
bunch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package scalable
import (
"github.com/duncanpierce/vector/runtimeExt"
"math/bits"
"unsafe"
)
type (
Bunch[Element any] interface {
Load(source Reader[Element])
Store(dest Writer[Element])
Active() Predicate
Mul(x, y Bunch[Element]) Bunch[Element]
}
array[Element any] interface {
[2]Element | [4]Element | [8]Element | [16]Element | [32]Element | [64]Element
}
bunch[Element any, Array array[Element]] struct {
vec Array
active Predicate
}
)
func NewBunch[T any]() (b Bunch[T]) {
var el T
size := uint64(unsafe.Sizeof(el))
elementSize := 1 << (64 - bits.LeadingZeros64(size) - 1)
if bits.OnesCount64(size) != 1 {
// Go to next size up if size isn't a power of 2
elementSize *= 2
}
vectorLength := runtimeExt.VectorLenBytes() / elementSize
switch vectorLength {
case 2:
b = &bunch[T, [2]T]{}
case 4:
b = &bunch[T, [4]T]{}
case 8:
b = &bunch[T, [8]T]{}
case 16:
b = &bunch[T, [16]T]{}
case 32:
b = &bunch[T, [32]T]{}
default:
b = &bunch[T, [64]T]{}
}
return
}
func (b *bunch[Element, Array]) Store(f Writer[Element]) {
b.active.ForActive(func(index int) {
f.Write(b.vec[index])
})
}
func (b *bunch[Element, Array]) Load(source Reader[Element]) {
b.active = Predicate{}
for i := 0; i < len(b.vec); i++ {
value, ok := source.Read()
if !ok {
return
}
b.vec[i] = value
b.active = b.active.Set(i, true)
}
}
func (b *bunch[Element, Array]) Active() Predicate {
return b.active
}