Skip to content

Commit f9e9fab

Browse files
authored
Merge pull request #530 from TheHippo/avx2-popcount
AVX2 popcount
2 parents 9e2afa4 + ca1e205 commit f9e9fab

6 files changed

Lines changed: 550 additions & 173 deletions

File tree

popcnt_amd64.s

Lines changed: 0 additions & 103 deletions
This file was deleted.

popcnt_asm.go

Lines changed: 0 additions & 68 deletions
This file was deleted.

popcnt_avx2_amd64.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//go:build amd64 && !appengine
2+
// +build amd64,!appengine
3+
4+
package roaring
5+
6+
// The functions below are implemented in popcnt_avx2_amd64.s using AVX2.
7+
// They are only used when the CPU supports AVX2 (see useAVX2); otherwise the
8+
// pure-Go fallbacks in popcnt_slices.go are used. This keeps behavior identical
9+
// on every target: appengine and non-amd64 builds compile popcnt_generic.go
10+
// instead, and amd64 CPUs without AVX2 take the scalar path at runtime.
11+
12+
//go:noescape
13+
func _hasAVX2() bool
14+
15+
//go:noescape
16+
func _popcntSliceAVX2(s []uint64) uint64
17+
18+
//go:noescape
19+
func _popcntMaskSliceAVX2(s, m []uint64) uint64
20+
21+
//go:noescape
22+
func _popcntAndSliceAVX2(s, m []uint64) uint64
23+
24+
//go:noescape
25+
func _popcntOrSliceAVX2(s, m []uint64) uint64
26+
27+
//go:noescape
28+
func _popcntXorSliceAVX2(s, m []uint64) uint64
29+
30+
// useAVX2 selects the AVX2 assembly implementations when the running CPU
31+
// supports AVX2. It is evaluated once at package initialization.
32+
var useAVX2 = _hasAVX2()
33+
34+
func popcntSlice(s []uint64) uint64 {
35+
if useAVX2 {
36+
return _popcntSliceAVX2(s)
37+
}
38+
return popcntSliceGo(s)
39+
}
40+
41+
func popcntMaskSlice(s, m []uint64) uint64 {
42+
if useAVX2 {
43+
return _popcntMaskSliceAVX2(s, m)
44+
}
45+
return popcntMaskSliceGo(s, m)
46+
}
47+
48+
func popcntAndSlice(s, m []uint64) uint64 {
49+
if useAVX2 {
50+
return _popcntAndSliceAVX2(s, m)
51+
}
52+
return popcntAndSliceGo(s, m)
53+
}
54+
55+
func popcntOrSlice(s, m []uint64) uint64 {
56+
if useAVX2 {
57+
return _popcntOrSliceAVX2(s, m)
58+
}
59+
return popcntOrSliceGo(s, m)
60+
}
61+
62+
func popcntXorSlice(s, m []uint64) uint64 {
63+
if useAVX2 {
64+
return _popcntXorSliceAVX2(s, m)
65+
}
66+
return popcntXorSliceGo(s, m)
67+
}

0 commit comments

Comments
 (0)