From c74d4e6857002ef81af12905fea0a366acf7060b Mon Sep 17 00:00:00 2001 From: Havij khor Date: Sat, 15 Feb 2020 00:08:52 +0330 Subject: [PATCH 1/6] Reformatted project file --- .../Standart.Hash.xxHash.csproj | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj b/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj index 5c204bc..18e478e 100644 --- a/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj +++ b/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj @@ -1,23 +1,28 @@  + + + netstandard2.0 + true + + + true - true x64 + false - true AnyCPU full + - + - + - - netstandard2.0 - + \ No newline at end of file From 2543dd0feb240cd6c5f0d099527e0d9258eefd6c Mon Sep 17 00:00:00 2001 From: Havij khor Date: Sat, 15 Feb 2020 00:11:02 +0330 Subject: [PATCH 2/6] Project file: Removed all configatuion and platform-target specific properties, thus default values will be used --- src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj b/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj index 18e478e..0715c41 100644 --- a/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj +++ b/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj @@ -7,17 +7,6 @@ - - true - x64 - - - - false - AnyCPU - full - - From f5b1c7d6b87ffb623a39a3161bed058ded6e098a Mon Sep 17 00:00:00 2001 From: Havij khor Date: Sat, 15 Feb 2020 00:25:16 +0330 Subject: [PATCH 3/6] Completely rewritten the main project file. Added support for multiple target frameworks --- .../Standart.Hash.xxHash.csproj | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj b/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj index 0715c41..fd6e319 100644 --- a/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj +++ b/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj @@ -1,15 +1,14 @@  - - netstandard2.0 - true - - - + + netstandard2.0; netstandard2.1; netcoreapp3.1; net48; + true + + + - From 214a4946ff8aa6da68d836b98a23ca1d7f1dc832 Mon Sep 17 00:00:00 2001 From: Havij khor Date: Sat, 15 Feb 2020 00:30:01 +0330 Subject: [PATCH 4/6] Updated nuget packages references to their latest version --- deps.props | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/deps.props b/deps.props index 3413d54..55aa275 100644 --- a/deps.props +++ b/deps.props @@ -2,12 +2,12 @@ 4.5.0 4.3.0 - 4.5.1 - 4.5.1 - 0.11.1 - 15.8.0 - 2.4.0 - 2.4.0 + 4.5.3 + 4.5.3 + 0.12 + 16.5.0 + 2.4.1 + 2.4.1 2.3.1 \ No newline at end of file From d9afd59a9351a70d626099f819e282ef169208ad Mon Sep 17 00:00:00 2001 From: Havij khor Date: Sat, 15 Feb 2020 00:30:41 +0330 Subject: [PATCH 5/6] Unit tests and benchmarks projects are now targeting .NET Core 3.1 --- src/Standart.Hash.xxHash.Perf/Standart.Hash.xxHash.Perf.csproj | 2 +- src/Standart.Hash.xxHash.Test/Standart.Hash.xxHash.Test.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Standart.Hash.xxHash.Perf/Standart.Hash.xxHash.Perf.csproj b/src/Standart.Hash.xxHash.Perf/Standart.Hash.xxHash.Perf.csproj index 6c9c03f..1287376 100644 --- a/src/Standart.Hash.xxHash.Perf/Standart.Hash.xxHash.Perf.csproj +++ b/src/Standart.Hash.xxHash.Perf/Standart.Hash.xxHash.Perf.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.0 + netcoreapp3.1 true diff --git a/src/Standart.Hash.xxHash.Test/Standart.Hash.xxHash.Test.csproj b/src/Standart.Hash.xxHash.Test/Standart.Hash.xxHash.Test.csproj index 7dfc6d9..8e93e0b 100644 --- a/src/Standart.Hash.xxHash.Test/Standart.Hash.xxHash.Test.csproj +++ b/src/Standart.Hash.xxHash.Test/Standart.Hash.xxHash.Test.csproj @@ -2,7 +2,7 @@ false - netcoreapp2.0 + netcoreapp3.1 full From 7b907932cd9921e150dad210e80a199d1cfcf384 Mon Sep 17 00:00:00 2001 From: Havij khor Date: Sat, 15 Feb 2020 01:07:38 +0330 Subject: [PATCH 6/6] using System.Numerics.BitOperations.RotateLeft() for taking advantage of CPU interiniscs for bit rotation --- src/Standart.Hash.xxHash/BitUtils.cs | 27 ++++++++ .../Standart.Hash.xxHash.csproj | 4 ++ src/Standart.Hash.xxHash/xxHash32.Unsafe.cs | 40 ++++++------ src/Standart.Hash.xxHash/xxHash64.Unsafe.cs | 64 +++++++++---------- 4 files changed, 83 insertions(+), 52 deletions(-) create mode 100644 src/Standart.Hash.xxHash/BitUtils.cs diff --git a/src/Standart.Hash.xxHash/BitUtils.cs b/src/Standart.Hash.xxHash/BitUtils.cs new file mode 100644 index 0000000..8d5c687 --- /dev/null +++ b/src/Standart.Hash.xxHash/BitUtils.cs @@ -0,0 +1,27 @@ +using System.Runtime.CompilerServices; + +namespace Standart.Hash.xxHash +{ + internal static class BitUtils + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static uint RotateLeft(uint value, int offset) + { +#if FCL_BITOPS + return System.Numerics.BitOperations.RotateLeft(value, offset); +#else + return (value << offset) | (value >> (32 - offset)); +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ulong RotateLeft(ulong value, int offset) // Taken help from: https://stackoverflow.com/a/48580489/5592276 + { +#if FCL_BITOPS + return System.Numerics.BitOperations.RotateLeft(value, offset); +#else + return (value << offset) | (value >> (64 - offset)); +#endif + } + } +} diff --git a/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj b/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj index fd6e319..e1433cd 100644 --- a/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj +++ b/src/Standart.Hash.xxHash/Standart.Hash.xxHash.csproj @@ -12,5 +12,9 @@ + + + FCL_BITOPS + \ No newline at end of file diff --git a/src/Standart.Hash.xxHash/xxHash32.Unsafe.cs b/src/Standart.Hash.xxHash/xxHash32.Unsafe.cs index 741cf95..b5e13a1 100644 --- a/src/Standart.Hash.xxHash/xxHash32.Unsafe.cs +++ b/src/Standart.Hash.xxHash/xxHash32.Unsafe.cs @@ -35,31 +35,31 @@ do { v1 += *((uint*)ptr) * p2; - v1 = (v1 << 13) | (v1 >> (32 - 13)); // rotl 13 + v1 = BitUtils.RotateLeft(v1, 13); // rotl 13 v1 *= p1; ptr += 4; v2 += *((uint*)ptr) * p2; - v2 = (v2 << 13) | (v2 >> (32 - 13)); // rotl 13 + v2 = BitUtils.RotateLeft(v2, 13); // rotl 13 v2 *= p1; ptr += 4; v3 += *((uint*)ptr) * p2; - v3 = (v3 << 13) | (v3 >> (32 - 13)); // rotl 13 + v3 = BitUtils.RotateLeft(v3, 13); // rotl 13 v3 *= p1; ptr += 4; v4 += *((uint*)ptr) * p2; - v4 = (v4 << 13) | (v4 >> (32 - 13)); // rotl 13 + v4 = BitUtils.RotateLeft(v4, 13); // rotl 13 v4 *= p1; ptr += 4; } while (ptr <= limit); - h32 = ((v1 << 1) | (v1 >> (32 - 1))) + // rotl 1 - ((v2 << 7) | (v2 >> (32 - 7))) + // rotl 7 - ((v3 << 12) | (v3 >> (32 - 12))) + // rotl 12 - ((v4 << 18) | (v4 >> (32 - 18))); // rotl 18 + h32 = BitUtils.RotateLeft(v1, 1) + // rotl 1 + BitUtils.RotateLeft(v2, 7) + // rotl 7 + BitUtils.RotateLeft(v3, 12) + // rotl 12 + BitUtils.RotateLeft(v4, 18); // rotl 18 } else { @@ -72,14 +72,14 @@ while (ptr <= end - 4) { h32 += *((uint*)ptr) * p3; - h32 = ((h32 << 17) | (h32 >> (32 - 17))) * p4; // (rotl 17) * p4 + h32 = BitUtils.RotateLeft(h32, 17) * p4; // (rotl 17) * p4 ptr += 4; } while (ptr < end) { h32 += *((byte*)ptr) * p5; - h32 = ((h32 << 11) | (h32 >> (32 - 11))) * p1; // (rotl 11) * p1 + h32 = BitUtils.RotateLeft(h32, 11) * p1; // (rotl 11) * p1 ptr += 1; } @@ -113,22 +113,22 @@ do { v1 += *((uint*)ptr) * p2; - v1 = (v1 << 13) | (v1 >> (32 - 13)); // rotl 13 + v1 = BitUtils.RotateLeft(v1, 13); // rotl 13 v1 *= p1; ptr += 4; v2 += *((uint*)ptr) * p2; - v2 = (v2 << 13) | (v2 >> (32 - 13)); // rotl 13 + v2 = BitUtils.RotateLeft(v2, 13); // rotl 13 v2 *= p1; ptr += 4; v3 += *((uint*)ptr) * p2; - v3 = (v3 << 13) | (v3 >> (32 - 13)); // rotl 13 + v3 = BitUtils.RotateLeft(v3, 13); // rotl 13 v3 *= p1; ptr += 4; v4 += *((uint*)ptr) * p2; - v4 = (v4 << 13) | (v4 >> (32 - 13)); // rotl 13 + v4 = BitUtils.RotateLeft(v4, 13); // rotl 13 v4 *= p1; ptr += 4; @@ -159,10 +159,10 @@ if (length >= 16) { - h32 = ((v1 << 1) | (v1 >> (32 - 1))) + // rotl 1 - ((v2 << 7) | (v2 >> (32 - 7))) + // rotl 7 - ((v3 << 12) | (v3 >> (32 - 12))) + // rotl 12 - ((v4 << 18) | (v4 >> (32 - 18))); // rotl 18 + h32 = BitUtils.RotateLeft(v1, 1) + // rotl 1 + BitUtils.RotateLeft(v2, 7) + // rotl 7 + BitUtils.RotateLeft(v3, 12) + // rotl 12 + BitUtils.RotateLeft(v4, 18); // rotl 18 } else { @@ -175,14 +175,14 @@ while (ptr <= end - 4) { h32 += *((uint*)ptr) * p3; - h32 = ((h32 << 17) | (h32 >> (32 - 17))) * p4; // (rotl 17) * p4 + h32 = BitUtils.RotateLeft(h32, 17) * p4; // (rotl 17) * p4 ptr += 4; } while (ptr < end) { h32 += *((byte*)ptr) * p5; - h32 = ((h32 << 11) | (h32 >> (32 - 11))) * p1; // (rotl 11) * p1 + h32 = BitUtils.RotateLeft(h32, 11) * p1; // (rotl 11) * p1 ptr += 1; } diff --git a/src/Standart.Hash.xxHash/xxHash64.Unsafe.cs b/src/Standart.Hash.xxHash/xxHash64.Unsafe.cs index b5d38bd..9208adf 100644 --- a/src/Standart.Hash.xxHash/xxHash64.Unsafe.cs +++ b/src/Standart.Hash.xxHash/xxHash64.Unsafe.cs @@ -36,56 +36,56 @@ do { v1 += *((ulong*)ptr) * p2; - v1 = (v1 << 31) | (v1 >> (64 - 31)); // rotl 31 + v1 = BitUtils.RotateLeft(v1, 31); // rotl 31 v1 *= p1; ptr += 8; v2 += *((ulong*)ptr) * p2; - v2 = (v2 << 31) | (v2 >> (64 - 31)); // rotl 31 + v2 = BitUtils.RotateLeft(v2, 31); // rotl 31 v2 *= p1; ptr += 8; v3 += *((ulong*)ptr) * p2; - v3 = (v3 << 31) | (v3 >> (64 - 31)); // rotl 31 + v3 = BitUtils.RotateLeft(v3, 31); // rotl 31 v3 *= p1; ptr += 8; v4 += *((ulong*)ptr) * p2; - v4 = (v4 << 31) | (v4 >> (64 - 31)); // rotl 31 + v4 = BitUtils.RotateLeft(v4, 31); // rotl 31 v4 *= p1; ptr += 8; } while (ptr <= limit); - h64 = ((v1 << 1) | (v1 >> (64 - 1))) + // rotl 1 - ((v2 << 7) | (v2 >> (64 - 7))) + // rotl 7 - ((v3 << 12) | (v3 >> (64 - 12))) + // rotl 12 - ((v4 << 18) | (v4 >> (64 - 18))); // rotl 18 + h64 = BitUtils.RotateLeft(v1, 1) + // rotl 1 + BitUtils.RotateLeft(v2, 7) + // rotl 7 + BitUtils.RotateLeft(v3, 12) + // rotl 12 + BitUtils.RotateLeft(v4, 18); // rotl 18 // merge round v1 *= p2; - v1 = (v1 << 31) | (v1 >> (64 - 31)); // rotl 31 + v1 = BitUtils.RotateLeft(v1, 31); // rotl 31 v1 *= p1; h64 ^= v1; h64 = h64 * p1 + p4; // merge round v2 *= p2; - v2 = (v2 << 31) | (v2 >> (64 - 31)); // rotl 31 + v2 = BitUtils.RotateLeft(v2, 31); // rotl 31 v2 *= p1; h64 ^= v2; h64 = h64 * p1 + p4; // merge round v3 *= p2; - v3 = (v3 << 31) | (v3 >> (64 - 31)); // rotl 31 + v3 = BitUtils.RotateLeft(v3, 31); // rotl 31 v3 *= p1; h64 ^= v3; h64 = h64 * p1 + p4; // merge round v4 *= p2; - v4 = (v4 << 31) | (v4 >> (64 - 31)); // rotl 31 + v4 = BitUtils.RotateLeft(v4, 31); // rotl 31 v4 *= p1; h64 ^= v4; h64 = h64 * p1 + p4; @@ -101,24 +101,24 @@ while (ptr <= end - 8) { ulong t1 = *((ulong*)ptr) * p2; - t1 = (t1 << 31) | (t1 >> (64 - 31)); // rotl 31 + t1 = BitUtils.RotateLeft(t1, 31); // rotl 31 t1 *= p1; h64 ^= t1; - h64 = ((h64 << 27) | (h64 >> (64 - 27))) * p1 + p4; // (rotl 27) * p1 + p4 + h64 = BitUtils.RotateLeft(h64, 27) * p1 + p4; // (rotl 27) * p1 + p4 ptr += 8; } if (ptr <= end - 4) { h64 ^= *((uint*)ptr) * p1; - h64 = ((h64 << 23) | (h64 >> (64 - 23))) * p2 + p3; // (rotl 27) * p2 + p3 + h64 = BitUtils.RotateLeft(h64, 23) * p2 + p3; // (rotl 27) * p2 + p3 ptr += 4; } while (ptr < end) { h64 ^= *((byte*)ptr) * p5; - h64 = ((h64 << 11) | (h64 >> (64 - 11))) * p1; // (rotl 11) * p1 + h64 = BitUtils.RotateLeft(h64, 11) * p1; // (rotl 11) * p1 ptr += 1; } @@ -152,22 +152,22 @@ do { v1 += *((ulong*)ptr) * p2; - v1 = (v1 << 31) | (v1 >> (64 - 31)); // rotl 31 + v1 = BitUtils.RotateLeft(v1, 31); // rotl 31 v1 *= p1; ptr += 8; v2 += *((ulong*)ptr) * p2; - v2 = (v2 << 31) | (v2 >> (64 - 31)); // rotl 31 + v2 = BitUtils.RotateLeft(v2, 31); // rotl 31 v2 *= p1; ptr += 8; v3 += *((ulong*)ptr) * p2; - v3 = (v3 << 31) | (v3 >> (64 - 31)); // rotl 31 + v3 = BitUtils.RotateLeft(v3, 31); // rotl 31 v3 *= p1; ptr += 8; v4 += *((ulong*)ptr) * p2; - v4 = (v4 << 31) | (v4 >> (64 - 31)); // rotl 31 + v4 = BitUtils.RotateLeft(v4, 31); // rotl 31 v4 *= p1; ptr += 8; @@ -198,35 +198,35 @@ if (length >= 32) { - h64 = ((v1 << 1) | (v1 >> (64 - 1))) + // rotl 1 - ((v2 << 7) | (v2 >> (64 - 7))) + // rotl 7 - ((v3 << 12) | (v3 >> (64 - 12))) + // rotl 12 - ((v4 << 18) | (v4 >> (64 - 18))); // rotl 18 + h64 = BitUtils.RotateLeft(v1, 1) + // rotl 1 + BitUtils.RotateLeft(v2, 7) + // rotl 7 + BitUtils.RotateLeft(v3, 12) + // rotl 12 + BitUtils.RotateLeft(v4, 18); // rotl 18 // merge round v1 *= p2; - v1 = (v1 << 31) | (v1 >> (64 - 31)); // rotl 31 + v1 = BitUtils.RotateLeft(v1, 31); // rotl 31 v1 *= p1; h64 ^= v1; h64 = h64 * p1 + p4; // merge round v2 *= p2; - v2 = (v2 << 31) | (v2 >> (64 - 31)); // rotl 31 + v2 = BitUtils.RotateLeft(v2, 31); // rotl 31 v2 *= p1; h64 ^= v2; h64 = h64 * p1 + p4; // merge round v3 *= p2; - v3 = (v3 << 31) | (v3 >> (64 - 31)); // rotl 31 + v3 = BitUtils.RotateLeft(v3, 31); // rotl 31 v3 *= p1; h64 ^= v3; h64 = h64 * p1 + p4; // merge round v4 *= p2; - v4 = (v4 << 31) | (v4 >> (64 - 31)); // rotl 31 + v4 = BitUtils.RotateLeft(v4, 31); // rotl 31 v4 *= p1; h64 ^= v4; h64 = h64 * p1 + p4; @@ -243,24 +243,24 @@ while (ptr <= end - 8) { ulong t1 = *((ulong*)ptr) * p2; - t1 = (t1 << 31) | (t1 >> (64 - 31)); // rotl 31 + t1 = BitUtils.RotateLeft(t1, 31); // rotl 31 t1 *= p1; h64 ^= t1; - h64 = ((h64 << 27) | (h64 >> (64 - 27))) * p1 + p4; // (rotl 27) * p1 + p4 + h64 = BitUtils.RotateLeft(h64, 27) * p1 + p4; // (rotl 27) * p1 + p4 ptr += 8; } if (ptr <= end - 4) { h64 ^= *((uint*)ptr) * p1; - h64 = ((h64 << 23) | (h64 >> (64 - 23))) * p2 + p3; // (rotl 27) * p2 + p3 + h64 = BitUtils.RotateLeft(h64, 23) * p2 + p3; // (rotl 27) * p2 + p3 ptr += 4; } while (ptr < end) { h64 ^= *((byte*)ptr) * p5; - h64 = ((h64 << 11) | (h64 >> (64 - 11))) * p1; // (rotl 11) * p1 + h64 = BitUtils.RotateLeft(h64, 11) * p1; // (rotl 11) * p1 ptr += 1; }