diff --git a/cmd/pilosa/main.go b/cmd/pilosa/main.go index 2ae81d95d..64b353cf6 100644 --- a/cmd/pilosa/main.go +++ b/cmd/pilosa/main.go @@ -93,6 +93,7 @@ func (m *Main) Run(args ...string) error { return err } else if addr == "" { return errors.New("port must be specified in config host") + } // Set up profiling. @@ -110,7 +111,7 @@ func (m *Main) Run(args ...string) error { cluster := m.Config.PilosaCluster() // Create index to store fragments. - index := pilosa.NewIndex() + index := pilosa.NewIndex("/tmp/") // Create executor for executing queries. e := pilosa.NewExecutor(index) diff --git a/popcnt.go b/popcnt.go index ff9085fc7..98b0e66c6 100644 --- a/popcnt.go +++ b/popcnt.go @@ -3,7 +3,7 @@ package pilosa // bit population count, take from // https://code.google.com/p/go/issues/detail?id=4988#c11 // credit: https://code.google.com/u/arnehormann/ -func popcount(x uint64) (n uint64) { +func popcntGo(x uint64) (n uint64) { x -= (x >> 1) & 0x5555555555555555 x = (x>>2)&0x3333333333333333 + x&0x3333333333333333 x += x >> 4 @@ -15,7 +15,7 @@ func popcount(x uint64) (n uint64) { func popcntSliceGo(s []uint64) uint64 { cnt := uint64(0) for _, x := range s { - cnt += popcount(x) + cnt += popcntGo(x) } return cnt } @@ -23,7 +23,7 @@ func popcntSliceGo(s []uint64) uint64 { func popcntMaskSliceGo(s, m []uint64) uint64 { cnt := uint64(0) for i := range s { - cnt += popcount(s[i] &^ m[i]) + cnt += popcntGo(s[i] &^ m[i]) } return cnt } @@ -31,7 +31,7 @@ func popcntMaskSliceGo(s, m []uint64) uint64 { func popcntAndSliceGo(s, m []uint64) uint64 { cnt := uint64(0) for i := range s { - cnt += popcount(s[i] & m[i]) + cnt += popcntGo(s[i] & m[i]) } return cnt } @@ -39,7 +39,7 @@ func popcntAndSliceGo(s, m []uint64) uint64 { func popcntOrSliceGo(s, m []uint64) uint64 { cnt := uint64(0) for i := range s { - cnt += popcount(s[i] | m[i]) + cnt += popcntGo(s[i] | m[i]) } return cnt } @@ -47,7 +47,7 @@ func popcntOrSliceGo(s, m []uint64) uint64 { func popcntXorSliceGo(s, m []uint64) uint64 { cnt := uint64(0) for i := range s { - cnt += popcount(s[i] ^ m[i]) + cnt += popcntGo(s[i] ^ m[i]) } return cnt } diff --git a/popcnt_amd64.s b/popcnt_amd64.s index 121ce7bfa..9718a9d1e 100644 --- a/popcnt_amd64.s +++ b/popcnt_amd64.s @@ -100,3 +100,10 @@ LOOP popcntXorSliceLoop popcntXorSliceEnd: MOVQ AX, ret+48(FP) RET + + +TEXT ·popcntAsm(SB),4,$0-16 + MOVQ x+0(FP), DX + POPCNTQ_DX_DX + MOVQ DX, ret+8(FP) + RET diff --git a/popcnt_asm.go b/popcnt_asm.go index c63dca950..b34613956 100644 --- a/popcnt_asm.go +++ b/popcnt_asm.go @@ -28,6 +28,9 @@ func popcntOrSliceAsm(s, m []uint64) uint64 func popcntXorSliceAsm(s, m []uint64) uint64 +//go:noescape +func popcntAsm(x uint64)uint64 + func popcntSlice(s []uint64) uint64 { if useAsm { return popcntSliceAsm(s) @@ -62,3 +65,11 @@ func popcntXorSlice(s, m []uint64) uint64 { } return popcntXorSliceGo(s, m) } + +func popcnt(x uint64) uint64{ + if useAsm { + return popcntAsm(x) + } + return popcntGo(x) +} + diff --git a/popcnt_generic.go b/popcnt_generic.go index b9665ac0a..01d381385 100644 --- a/popcnt_generic.go +++ b/popcnt_generic.go @@ -7,3 +7,4 @@ func popcntMaskSlice(s, m []uint64) uint64 { return popcntMaskSliceGo(s, m) } func popcntAndSlice(s, m []uint64) uint64 { return popcntAndSliceGo(s, m) } func popcntOrSlice(s, m []uint64) uint64 { return popcntOrSliceGo(s, m) } func popcntXorSlice(s, m []uint64) uint64 { return popcntXorSliceGo(s, m) } +func popcnt(s uint64) uint64 { return popcntGo(s)} diff --git a/popcnt_test.go b/popcnt_test.go new file mode 100644 index 000000000..a256684d1 --- /dev/null +++ b/popcnt_test.go @@ -0,0 +1,75 @@ +package pilosa + +import "testing" + +func BenchmarkPopcntAsm(b *testing.B) { + // run the Fib function b.N times + for n := 0; n < b.N; n++ { + popcntAsm(0xdeadbeef) + } +} + +func BenchmarkPopcntGo(b *testing.B) { + // run the Fib function b.N times + for n := 0; n < b.N; n++ { + popcntGo(0xdeadbeef) + } +} + +func getData() []uint64 { + return []uint64{ + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + 0xdeadbeef, + } +} + +func BenchmarkPopcntSliceGo(b *testing.B) { + d := getData() + for n := 0; n < b.N; n++ { + popcntSliceGo(d) + } +} + +func BenchmarkPopcntSliceAsm(b *testing.B) { + d := getData() + for n := 0; n < b.N; n++ { + popcntSliceAsm(d) + } +} + +func BenchmarkPopcntSlice(b *testing.B) { + d := getData() + for n := 0; n < b.N; n++ { + popcntSlice(d) + } +}