[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