Skip to content

Commit

Permalink
Merge 783a341 into 538d003
Browse files Browse the repository at this point in the history
  • Loading branch information
mmcloughlin committed May 20, 2018
2 parents 538d003 + 783a341 commit 1116b0a
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 17 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Expand Up @@ -13,7 +13,9 @@ before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
- go get github.com/klauspost/asmfmt/cmd/asmfmt
script:
- test -z "$(asmfmt -l *.s)"
- go test -v -covermode=count -coverprofile=profile.cov
after_success:
- goveralls -coverprofile=profile.cov -service=travis-ci
56 changes: 56 additions & 0 deletions asm_x86.s
@@ -0,0 +1,56 @@
// +build amd64,go1.6

#include "textflag.h"

// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
TEXT ·cpuid(SB), NOSPLIT, $0-24
MOVL eaxArg+0(FP), AX
MOVL ecxArg+4(FP), CX
CPUID
MOVL AX, eax+8(FP)
MOVL BX, ebx+12(FP)
MOVL CX, ecx+16(FP)
MOVL DX, edx+20(FP)
RET

// func EncodeInt(lat, lng float64) uint64
TEXT ·EncodeInt(SB), NOSPLIT, $0
CMPB ·useAsm(SB), $1
JNE fallback

#define LATF X0
#define LATI R8
#define LNGF X1
#define LNGI R9
#define TEMP R10
#define GHSH R11
#define MASK BX

MOVSD lat+0(FP), LATF
MOVSD lng+8(FP), LNGF

MOVQ $0x5555555555555555, MASK

MULSD $(0.005555555555555556), LATF
ADDSD $(1.5), LATF

MULSD $(0.002777777777777778), LNGF
ADDSD $(1.5), LNGF

MOVQ LNGF, LNGI
SHRQ $20, LNGI

MOVQ LATF, LATI
SHRQ $20, LATI
PDEPQ MASK, LATI, GHSH

PDEPQ MASK, LNGI, TEMP

SHLQ $1, TEMP
XORQ TEMP, GHSH

MOVQ GHSH, ret+16(FP)
RET

fallback:
JMP ·encodeInt(SB)
21 changes: 6 additions & 15 deletions benchmark_test.go
@@ -1,28 +1,19 @@
package geohash

import "testing"
import (
"testing"
)

func randomPoints(n int) [][2]float64 {
var points [][2]float64
for i := 0; i < n; i++ {
lat, lon := RandomPoint()
points = append(points, [2]float64{lat, lon})
}
return points
}
const lat, lng = 33.0, -72.0

func BenchmarkEncode(b *testing.B) {
points := randomPoints(b.N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
Encode(points[i][0], points[i][1])
_ = Encode(lat, lng)
}
}

func BenchmarkEncodeInt(b *testing.B) {
points := randomPoints(b.N)
b.ResetTimer()
for i := 0; i < b.N; i++ {
EncodeInt(points[i][0], points[i][1])
_ = EncodeInt(lat, lng)
}
}
11 changes: 9 additions & 2 deletions geohash.go
Expand Up @@ -2,7 +2,9 @@
// geohashes.
package geohash

import "math"
import (
"math"
)

// Encode the point (lat, lng) as a string geohash with the standard 12
// characters of precision.
Expand All @@ -20,7 +22,12 @@ func EncodeWithPrecision(lat, lng float64, chars uint) string {
}

// EncodeInt encodes the point (lat, lng) to a 64-bit integer geohash.
func EncodeInt(lat, lng float64) uint64 {
func EncodeInt(lat, lng float64) uint64

// encodeInt provides a Go implementation of integer geohash. This is the
// default implementation of EncodeInt, but optimized versions are provided
// for certain architectures.
func encodeInt(lat, lng float64) uint64 {
latInt := encodeRange(lat, 90)
lngInt := encodeRange(lng, 180)
return interleave(latInt, lngInt)
Expand Down
24 changes: 24 additions & 0 deletions geohash_x86.go
@@ -0,0 +1,24 @@
// +build amd64,go1.6

package geohash

// useAsm flag determines whether the assembly version of EncodeInt will be
// used. By Default we fall back to encodeInt.
var useAsm bool

// cpuid executes the CPUID instruction to obtain processor identification and
// feature information.
func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)

// hasBMI2 returns whether the CPU supports Bit Manipulation Instruction Set
// 2.
func hasBMI2() bool {
_, ebx, _, _ := cpuid(7, 0)
return ebx&(1<<8) != 0
}

// init determines whether to use assembly version by performing CPU feature
// check.
func init() {
useAsm = hasBMI2()
}
7 changes: 7 additions & 0 deletions stubs.s
@@ -0,0 +1,7 @@
// +build !amd64 !go1.6

// Define NOSPLIT ourselves since "textflag.h" is missing in old Go versions.
#define NOSPLIT 4

TEXT ·EncodeInt(SB), NOSPLIT, $0
JMP ·encodeInt(SB)

0 comments on commit 1116b0a

Please sign in to comment.