[Pkg-privacy-commits] [golang-siphash-dev] 19/23: Up to 2x faster hash.Hash version.
Ximin Luo
infinity0 at moszumanska.debian.org
Sat Aug 22 12:55:54 UTC 2015
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository golang-siphash-dev.
commit f1bd7f661761f779e943732dba198180f3efd8b6
Author: Dmitry Chestnykh <dmitry at codingrobots.com>
Date: Fri Jan 25 14:31:24 2013 +0100
Up to 2x faster hash.Hash version.
Inlined rounds, made padding faster.
The shorter the message, the greater the speedup.
benchmark old ns/op new ns/op delta
BenchmarkFull8 224 100 -55.36%
BenchmarkFull16 242 115 -52.48%
BenchmarkFull40 243 117 -51.85%
BenchmarkFull64 347 213 -38.62%
BenchmarkFull128 347 219 -36.89%
BenchmarkFull1K 2299 2042 -11.18%
BenchmarkFull8K 17382 15984 -8.04%
benchmark old MB/s new MB/s speedup
BenchmarkFull8 35.64 79.43 2.23x
BenchmarkFull16 65.86 138.80 2.11x
BenchmarkFull40 98.42 203.96 2.07x
BenchmarkFull64 184.31 299.72 1.63x
BenchmarkFull128 368.14 582.74 1.58x
BenchmarkFull1K 445.40 501.46 1.13x
BenchmarkFull8K 471.29 512.51 1.09x
---
siphash.go | 171 +++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 122 insertions(+), 49 deletions(-)
diff --git a/siphash.go b/siphash.go
index a0c3390..a8d73a0 100644
--- a/siphash.go
+++ b/siphash.go
@@ -16,12 +16,6 @@ const (
BlockSize = 8
// The size of hash output in bytes.
Size = 8
-
- // NOTE: Hash() doesn't use the following two constants.
- // The number of c iterations.
- cRounds = 2
- // The number of d iterations.
- dRounds = 4
)
type digest struct {
@@ -59,7 +53,7 @@ func (d *digest) Size() int { return Size }
func (d *digest) BlockSize() int { return BlockSize }
-func block(d *digest, p []uint8) {
+func blocks(d *digest, p []uint8) {
v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3
for len(p) >= BlockSize {
@@ -67,25 +61,45 @@ func block(d *digest, p []uint8) {
uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
v3 ^= m
- for i := 0; i < cRounds; i++ {
- v0 += v1
- v1 = v1<<13 | v1>>(64-13)
- v1 ^= v0
- v0 = v0<<32 | v0>>(64-32)
-
- v2 += v3
- v3 = v3<<16 | v3>>(64-16)
- v3 ^= v2
-
- v0 += v3
- v3 = v3<<21 | v3>>(64-21)
- v3 ^= v0
-
- v2 += v1
- v1 = v1<<17 | v1>>(64-17)
- v1 ^= v2
- v2 = v2<<32 | v2>>(64-32)
- }
+
+ // Round 1.
+ v0 += v1
+ v1 = v1<<13 | v1>>(64-13)
+ v1 ^= v0
+ v0 = v0<<32 | v0>>(64-32)
+
+ v2 += v3
+ v3 = v3<<16 | v3>>(64-16)
+ v3 ^= v2
+
+ v0 += v3
+ v3 = v3<<21 | v3>>(64-21)
+ v3 ^= v0
+
+ v2 += v1
+ v1 = v1<<17 | v1>>(64-17)
+ v1 ^= v2
+ v2 = v2<<32 | v2>>(64-32)
+
+ // Round 2.
+ v0 += v1
+ v1 = v1<<13 | v1>>(64-13)
+ v1 ^= v0
+ v0 = v0<<32 | v0>>(64-32)
+
+ v2 += v3
+ v3 = v3<<16 | v3>>(64-16)
+ v3 ^= v2
+
+ v0 += v3
+ v3 = v3<<21 | v3>>(64-21)
+ v3 ^= v0
+
+ v2 += v1
+ v1 = v1<<17 | v1>>(64-17)
+ v1 ^= v2
+ v2 = v2<<32 | v2>>(64-32)
+
v0 ^= m
p = p[BlockSize:]
@@ -104,14 +118,14 @@ func (d *digest) Write(p []byte) (nn int, err error) {
}
d.nx += copy(d.x[d.nx:], p)
if d.nx == BlockSize {
- block(d, d.x[:])
+ blocks(d, d.x[:])
d.nx = 0
}
p = p[n:]
}
if len(p) >= BlockSize {
n := len(p) &^ (BlockSize - 1)
- block(d, p[:n])
+ blocks(d, p[:n])
p = p[n:]
}
if len(p) > 0 {
@@ -124,32 +138,91 @@ func (d0 *digest) Sum64() uint64 {
// Make a copy of d0 so that caller can keep writing and summing.
d := *d0
- var zeros [8]byte
- d.t += uint8(d.nx)
- d.Write(zeros[:7-d.nx])
- d.Write([]byte{d.t})
+ for i := d.nx; i < BlockSize-1; i++ {
+ d.x[i] = 0
+ }
+ d.x[7] = d.t + uint8(d.nx)
+ blocks(&d, d.x[:])
v0, v1, v2, v3 := d.v0, d.v1, d.v2, d.v3
v2 ^= 0xff
- for i := 0; i < dRounds; i++ {
- v0 += v1
- v1 = v1<<13 | v1>>(64-13)
- v1 ^= v0
- v0 = v0<<32 | v0>>(64-32)
- v2 += v3
- v3 = v3<<16 | v3>>(64-16)
- v3 ^= v2
-
- v0 += v3
- v3 = v3<<21 | v3>>(64-21)
- v3 ^= v0
+ // Round 1.
+ v0 += v1
+ v1 = v1<<13 | v1>>(64-13)
+ v1 ^= v0
+ v0 = v0<<32 | v0>>(64-32)
+
+ v2 += v3
+ v3 = v3<<16 | v3>>(64-16)
+ v3 ^= v2
+
+ v0 += v3
+ v3 = v3<<21 | v3>>(64-21)
+ v3 ^= v0
+
+ v2 += v1
+ v1 = v1<<17 | v1>>(64-17)
+ v1 ^= v2
+ v2 = v2<<32 | v2>>(64-32)
+
+ // Round 2.
+ v0 += v1
+ v1 = v1<<13 | v1>>(64-13)
+ v1 ^= v0
+ v0 = v0<<32 | v0>>(64-32)
+
+ v2 += v3
+ v3 = v3<<16 | v3>>(64-16)
+ v3 ^= v2
+
+ v0 += v3
+ v3 = v3<<21 | v3>>(64-21)
+ v3 ^= v0
+
+ v2 += v1
+ v1 = v1<<17 | v1>>(64-17)
+ v1 ^= v2
+ v2 = v2<<32 | v2>>(64-32)
+
+ // Round 3.
+ v0 += v1
+ v1 = v1<<13 | v1>>(64-13)
+ v1 ^= v0
+ v0 = v0<<32 | v0>>(64-32)
+
+ v2 += v3
+ v3 = v3<<16 | v3>>(64-16)
+ v3 ^= v2
+
+ v0 += v3
+ v3 = v3<<21 | v3>>(64-21)
+ v3 ^= v0
+
+ v2 += v1
+ v1 = v1<<17 | v1>>(64-17)
+ v1 ^= v2
+ v2 = v2<<32 | v2>>(64-32)
+
+ // Round 4.
+ v0 += v1
+ v1 = v1<<13 | v1>>(64-13)
+ v1 ^= v0
+ v0 = v0<<32 | v0>>(64-32)
+
+ v2 += v3
+ v3 = v3<<16 | v3>>(64-16)
+ v3 ^= v2
+
+ v0 += v3
+ v3 = v3<<21 | v3>>(64-21)
+ v3 ^= v0
+
+ v2 += v1
+ v1 = v1<<17 | v1>>(64-17)
+ v1 ^= v2
+ v2 = v2<<32 | v2>>(64-32)
- v2 += v1
- v1 = v1<<17 | v1>>(64-17)
- v1 ^= v2
- v2 = v2<<32 | v2>>(64-32)
- }
return v0 ^ v1 ^ v2 ^ v3
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/golang-siphash-dev.git
More information about the Pkg-privacy-commits
mailing list