From 5878fcc086b2472a2b60dc855f8ecc501675796f Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 22 Dec 2016 08:25:03 -0800 Subject: [PATCH] bit-rot: Default to sha256 on ARM64. (#3488) This is to utilize an optimized version of sha256 checksum which @fwessels implemented. blake2b lacks such optimizations on ARM platform, this can provide us significant boost in performance. blake2b on ARM64 as expected would be slower. ``` BenchmarkSize1K-4 30000 44015 ns/op 23.26 MB/s BenchmarkSize8K-4 5000 335448 ns/op 24.42 MB/s BenchmarkSize32K-4 1000 1333960 ns/op 24.56 MB/s BenchmarkSize128K-4 300 5328286 ns/op 24.60 MB/s ``` sha256 on ARM64 is faster by orders of magnitude giving close to AVX performance of blake2b. ``` BenchmarkHash8Bytes-4 1000000 1446 ns/op 5.53 MB/s BenchmarkHash1K-4 500000 3229 ns/op 317.12 MB/s BenchmarkHash8K-4 100000 14430 ns/op 567.69 MB/s BenchmarkHash1M-4 1000 1640126 ns/op 639.33 MB/s ``` --- cmd/erasure-utils.go | 14 +++++++++----- cmd/xl-v1-metadata.go | 26 +++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/cmd/erasure-utils.go b/cmd/erasure-utils.go index 498997eba..5897d5e02 100644 --- a/cmd/erasure-utils.go +++ b/cmd/erasure-utils.go @@ -24,6 +24,7 @@ import ( "sync" "github.com/klauspost/reedsolomon" + "github.com/minio/sha256-simd" "golang.org/x/crypto/blake2b" ) @@ -37,23 +38,26 @@ func newHashWriters(diskCount int, algo string) []hash.Hash { } // newHash - gives you a newly allocated hash depending on the input algorithm. -func newHash(algo string) hash.Hash { +func newHash(algo string) (h hash.Hash) { switch algo { + case "sha256": + // sha256 checksum specially on ARM64 platforms or whenever + // requested as dictated by `xl.json` entry. + h = sha256.New() case "blake2b": // ignore the error, because New512 without a key never fails // New512 only returns a non-nil error, if the length of the passed // key > 64 bytes - but we use blake2b as hash fucntion (no key) - h, _ := blake2b.New512(nil) - return h + h, _ = blake2b.New512(nil) // Add new hashes here. default: // Default to blake2b. // ignore the error, because New512 without a key never fails // New512 only returns a non-nil error, if the length of the passed // key > 64 bytes - but we use blake2b as hash fucntion (no key) - h, _ := blake2b.New512(nil) - return h + h, _ = blake2b.New512(nil) } + return h } // Hash buffer pool is a pool of reusable diff --git a/cmd/xl-v1-metadata.go b/cmd/xl-v1-metadata.go index 37b21deee..8edd7d2ba 100644 --- a/cmd/xl-v1-metadata.go +++ b/cmd/xl-v1-metadata.go @@ -20,6 +20,7 @@ import ( "encoding/json" "errors" "path" + "runtime" "sort" "sync" "time" @@ -54,9 +55,28 @@ type checkSumInfo struct { } // Constant indicates current bit-rot algo used when creating objects. -const ( - bitRotAlgo = "blake2b" -) +// Depending on the architecture we are choosing a different checksum. +var bitRotAlgo = getDefaultBitRotAlgo() + +// Get the default bit-rot algo depending on the architecture. +// Currently this function defaults to "blake2b" as the preferred +// checksum algorithm on all architectures except ARM64. On ARM64 +// we use sha256 (optimized using sha2 instructions of ARM NEON chip). +func getDefaultBitRotAlgo() string { + switch runtime.GOARCH { + case "arm64": + // As a special case for ARM64 we use an optimized + // version of hash i.e sha256. This is done so that + // blake2b is sub-optimal and slower on ARM64. + // This would also allows erasure coded writes + // on ARM64 servers to be on-par with their + // counter-part X86_64 servers. + return "sha256" + default: + // Default for all other architectures we use blake2b. + return "blake2b" + } +} // erasureInfo - carries erasure coding related information, block // distribution and checksums.