]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add runtime.cmpstring and bytes.Compare
authorDave Cheney <dave@cheney.net>
Tue, 24 Mar 2015 09:37:10 +0000 (09:37 +0000)
committerDave Cheney <dave@cheney.net>
Wed, 25 Mar 2015 22:46:39 +0000 (22:46 +0000)
Update #10007

Implement runtime.cmpstring and bytes.Compare in asm for arm.

benchmark                                old ns/op     new ns/op     delta
BenchmarkCompareBytesEqual               254           91.4          -64.02%
BenchmarkCompareBytesToNil               41.5          37.6          -9.40%
BenchmarkCompareBytesEmpty               40.7          37.6          -7.62%
BenchmarkCompareBytesIdentical           255           96.3          -62.24%
BenchmarkCompareBytesSameLength          125           60.9          -51.28%
BenchmarkCompareBytesDifferentLength     133           60.9          -54.21%
BenchmarkCompareBytesBigUnaligned        17985879      5669706       -68.48%
BenchmarkCompareBytesBig                 17097634      4926798       -71.18%
BenchmarkCompareBytesBigIdentical        16861941      4389206       -73.97%

benchmark                             old MB/s     new MB/s     speedup
BenchmarkCompareBytesBigUnaligned     58.30        184.95       3.17x
BenchmarkCompareBytesBig              61.33        212.83       3.47x
BenchmarkCompareBytesBigIdentical     62.19        238.90       3.84x

This is a collaboration between Josh Bleecher Snyder and myself.

Change-Id: Ib3944b8c410d0e12135c2ba9459bfe131df48edd
Reviewed-on: https://go-review.googlesource.com/8010
Reviewed-by: Keith Randall <khr@golang.org>
src/bytes/compare_test.go
src/runtime/asm_arm.s
src/runtime/noasm.go

index 63522374ee0403f81210f9a6381578e974551527..f2d81d5310c0b915eeb304a8bae03f4b60d47d82 100644 (file)
@@ -17,6 +17,8 @@ var compareTests = []struct {
        {[]byte("a"), []byte(""), 1},
        {[]byte(""), []byte("a"), -1},
        {[]byte("abc"), []byte("abc"), 0},
+       {[]byte("abd"), []byte("abc"), 1},
+       {[]byte("abc"), []byte("abd"), -1},
        {[]byte("ab"), []byte("abc"), -1},
        {[]byte("abc"), []byte("ab"), 1},
        {[]byte("x"), []byte("ab"), 1},
@@ -27,6 +29,7 @@ var compareTests = []struct {
        {[]byte("abcdefgh"), []byte("abcdefgh"), 0},
        {[]byte("abcdefghi"), []byte("abcdefghi"), 0},
        {[]byte("abcdefghi"), []byte("abcdefghj"), -1},
+       {[]byte("abcdefghj"), []byte("abcdefghi"), 1},
        // nil tests
        {nil, nil, 0},
        {[]byte(""), nil, 0},
index cf1c9d13025819a9c61e9cea076f9936b65b14ec..4074e503cc54a66b04f6f2d81d4f9ad998b9cb93 100644 (file)
@@ -782,6 +782,57 @@ eq:
        MOVB    R0, ret+8(FP)
        RET
 
+TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
+       MOVW    s1_base+0(FP), R2
+       MOVW    s1_len+4(FP), R0
+       MOVW    s2_base+8(FP), R3
+       MOVW    s2_len+12(FP), R1
+       BL      runtime·cmpbody(SB)
+       MOVW    R8, ret+16(FP)
+       RET
+
+TEXT bytes·Compare(SB),NOSPLIT,$0-28
+       MOVW    s1+0(FP), R2
+       MOVW    s1+4(FP), R0
+       MOVW    s2+12(FP), R3
+       MOVW    s2+16(FP), R1
+       BL      runtime·cmpbody(SB)
+       MOVW    R8, ret+24(FP)
+       RET
+
+// On entry:
+// R0 is the length of s1
+// R1 is the length of s2
+// R2 points to the start of s1
+// R3 points to the start of s2
+//
+// On exit:
+// R8 is -1/0/+1
+// R5, R4, and R6 are clobbered
+TEXT runtime·cmpbody(SB),NOSPLIT,$-4-0
+       CMP     R0, R1
+       MOVW    R0, R6
+       MOVW.LT R1, R6  // R6 is min(R0, R1)
+
+       ADD     R2, R6  // R2 is current byte in s1, R6 is last byte in s1 to compare
+loop:
+       CMP     R2, R6
+       BEQ     samebytes // all compared bytes were the same; compare lengths
+       MOVBU.P 1(R2), R4
+       MOVBU.P 1(R3), R5
+       CMP     R4, R5
+       BEQ     loop
+       // bytes differed
+       MOVW.LT $1, R8
+       MOVW.GT $-1, R8
+       RET
+samebytes:
+       CMP     R0, R1
+       MOVW.LT $1, R8
+       MOVW.GT $-1, R8
+       MOVW.EQ $0, R8
+       RET
+
 // eqstring tests whether two strings are equal.
 // The compiler guarantees that strings passed
 // to eqstring have equal length.
index 4b3c577a21c9279c857d216d45b15387fe91ff85..ab9c7447891fc13668ea658e136af625a655b59e 100644 (file)
@@ -2,9 +2,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Routines that are implemented in assembly in asm_{amd64,386}.s
+// Routines that are implemented in assembly in asm_{amd64,386,arm}.s
 
-// +build arm arm64 ppc64 ppc64le
+// +build arm64 ppc64 ppc64le
 
 package runtime