From cf4f8e0c34f0dd10bc9c329277c72fb4c4489f03 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Sun, 3 Jul 2016 12:58:02 -0700 Subject: [PATCH] Fix benchmarks to report proper values. (#7) ``` $ go test -run=NONE -bench . PASS BenchmarkHash64-4 1000000 1036 ns/op 61.77 MB/s BenchmarkHash128-4 2000000 801 ns/op 159.67 MB/s BenchmarkHash1K-4 500000 2464 ns/op 415.53 MB/s BenchmarkHash8K-4 200000 11212 ns/op 730.60 MB/s BenchmarkHash32K-4 30000 40766 ns/op 803.80 MB/s BenchmarkHash128K-4 10000 163170 ns/op 803.28 MB/s ok github.com/minio/blake2b-simd 10.298s ``` --- blake2b_test.go | 47 ++++++++++--------------- compressAvx2_noasm.go | 23 ------------ compressAvx_amd64.go | 40 +++++++++++++++++++++ compress_amd64.s => compressAvx_amd64.s | 0 compress_amd64.go | 30 ++-------------- cpuid.go | 2 +- 6 files changed, 63 insertions(+), 79 deletions(-) delete mode 100644 compressAvx2_noasm.go create mode 100644 compressAvx_amd64.go rename compress_amd64.s => compressAvx_amd64.s (100%) diff --git a/blake2b_test.go b/blake2b_test.go index e92c341..5ec56fa 100644 --- a/blake2b_test.go +++ b/blake2b_test.go @@ -601,50 +601,41 @@ var goldenKeyed = []string{ var bench = New512() var buf = make([]byte, 128*1024) +func benchmarkSize(b *testing.B, size int) { + b.SetBytes(int64(size)) + for i := 0; i < b.N; i++ { + bench.Reset() + bench.Write(buf[:size]) + bench.Sum(nil) + } +} + // Benchmark writes of 64 bytes. func BenchmarkHash64(b *testing.B) { - b.SetBytes(64) - for i := 0; i < b.N; i++ { - Sum512(buf[:64]) - } + benchmarkSize(b, 64) } // Benchmark writes of 128 bytes. func BenchmarkHash128(b *testing.B) { - b.SetBytes(128) - for i := 0; i < b.N; i++ { - Sum512(buf[:128]) - } + benchmarkSize(b, 128) } // Benchmark writes of 1KiB bytes. -func BenchmarkWrite1K(b *testing.B) { - b.SetBytes(1024) - for i := 0; i < b.N; i++ { - bench.Write(buf[:1024]) - } +func BenchmarkHash1K(b *testing.B) { + benchmarkSize(b, 1024) } // Benchmark writes of 8KiB bytes. -func BenchmarkWrite8K(b *testing.B) { - b.SetBytes(int64(len(buf))) - for i := 0; i < b.N; i++ { - bench.Write(buf[:8192]) - } +func BenchmarkHash8K(b *testing.B) { + benchmarkSize(b, 8*1024) } // Benchmark writes of 32KiB bytes. -func BenchmarkWrite32K(b *testing.B) { - b.SetBytes(int64(len(buf))) - for i := 0; i < b.N; i++ { - bench.Write(buf[:32*1024]) - } +func BenchmarkHash32K(b *testing.B) { + benchmarkSize(b, 32*1024) } // Benchmark writes of 128KiB bytes. -func BenchmarkWrite128K(b *testing.B) { - b.SetBytes(int64(len(buf))) - for i := 0; i < b.N; i++ { - bench.Write(buf) - } +func BenchmarkHash128K(b *testing.B) { + benchmarkSize(b, 128*1024) } diff --git a/compressAvx2_noasm.go b/compressAvx2_noasm.go deleted file mode 100644 index 85de8fb..0000000 --- a/compressAvx2_noasm.go +++ /dev/null @@ -1,23 +0,0 @@ -//+build !amd64 noasm appengine - -/* - * Minio Cloud Storage, (C) 2016 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package blake2b - -func compressAvx2(d *digest, p []uint8) { - compressGeneric(d, p) -} diff --git a/compressAvx_amd64.go b/compressAvx_amd64.go new file mode 100644 index 0000000..7bed76c --- /dev/null +++ b/compressAvx_amd64.go @@ -0,0 +1,40 @@ +//+build !noasm +//+build !appengine + +/* + * Minio Cloud Storage, (C) 2016 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package blake2b + +//go:noescape +func blockAVXLoop(p []uint8, in, iv, t, f, shffle, out []uint64) + +func compressAVX(d *digest, p []uint8) { + + in := make([]uint64, 8, 8) + out := make([]uint64, 8, 8) + + shffle := make([]uint64, 2, 2) + // vector for PSHUFB instruction + shffle[0] = 0x0201000706050403 + shffle[1] = 0x0a09080f0e0d0c0b + + in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7] = d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] + + blockAVXLoop(p, in, iv[:], d.t[:], d.f[:], shffle, out) + + d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7] +} diff --git a/compress_amd64.s b/compressAvx_amd64.s similarity index 100% rename from compress_amd64.s rename to compressAvx_amd64.s diff --git a/compress_amd64.go b/compress_amd64.go index d09d1e0..1b6b380 100644 --- a/compress_amd64.go +++ b/compress_amd64.go @@ -1,6 +1,3 @@ -//+build !noasm -//+build !appengine - /* * Minio Cloud Storage, (C) 2016 Minio, Inc. * @@ -19,34 +16,13 @@ package blake2b -//go:noescape -func blockAVXLoop(p []uint8, in, iv, t, f, shffle, out []uint64) - -func compressAVX(d *digest, p []uint8) { - - in := make([]uint64, 8, 8) - out := make([]uint64, 8, 8) - - shffle := make([]uint64, 2, 2) - // vector for PSHUFB instruction - shffle[0] = 0x0201000706050403 - shffle[1] = 0x0a09080f0e0d0c0b - - in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7] = d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] - - blockAVXLoop(p, in, iv[:], d.t[:], d.f[:], shffle, out) - - d.h[0], d.h[1], d.h[2], d.h[3], d.h[4], d.h[5], d.h[6], d.h[7] = out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7] -} - func compress(d *digest, p []uint8) { // Verifies if AVX2 or AVX is available, use optimized code path. if avx2 { compressAVX2(d, p) - return } else if avx { compressAVX(d, p) - return - } // else { fallback to generic approach. - compressGeneric(d, p) + } else { + compressGeneric(d, p) + } } diff --git a/cpuid.go b/cpuid.go index e849867..9d08bc6 100644 --- a/cpuid.go +++ b/cpuid.go @@ -40,8 +40,8 @@ func haveAVX() bool { // haveAVX2 returns true if when there is AVX2 support func haveAVX2() bool { - mfi, _, _, _ := cpuid(0) + // Check AVX2, AVX2 requires OS support, but BMI1/2 don't. if mfi >= 7 && haveAVX() { _, ebx, _, _ := cpuidex(7, 0)