Optimize FormattingHelpers.CountHexDigits using Lzcnt.LeadingZeroCount (#19006)
authorEgor Bogatov <egorbo@gmail.com>
Fri, 26 Oct 2018 06:07:08 +0000 (09:07 +0300)
committerStephen Toub <stoub@microsoft.com>
Fri, 26 Oct 2018 06:07:08 +0000 (23:07 -0700)
* Optimize CountHexDigits using Lzcnt

* shift bits instead

* use Lzcnt only on 64 bit

* Optimize Buffer.Utilities.SelectBucketIndex()

* #if HAS_INTRINSICS

* remove HAS_INTRINSICS

* remove HAS_INTRINSICS

src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs
src/System.Private.CoreLib/shared/System/Buffers/Utilities.cs

index b6140ad..8982803 100644 (file)
@@ -4,6 +4,7 @@
 
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics.X86;
 
 namespace System.Buffers.Text
 {
@@ -103,8 +104,11 @@ namespace System.Buffers.Text
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public static int CountHexDigits(ulong value)
         {
-            // TODO: When x86 intrinsic support comes online, experiment with implementing this using lzcnt.
-            // return 16 - (int)((uint)Lzcnt.LeadingZeroCount(value | 1) >> 3);
+            if (Lzcnt.IsSupported && IntPtr.Size == 8)
+            {
+                int right = 64 - (int)Lzcnt.LeadingZeroCount(value | 1);
+                return (right + 3) >> 2;
+            }
 
             int digits = 1;
 
index b675100..628449c 100644 (file)
@@ -4,6 +4,7 @@
 
 using System.Diagnostics;
 using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics.X86;
 
 namespace System.Buffers
 {
@@ -13,6 +14,11 @@ namespace System.Buffers
         internal static int SelectBucketIndex(int bufferSize)
         {
             Debug.Assert(bufferSize >= 0);
+            if (Lzcnt.IsSupported)
+            {
+                uint bits = ((uint)bufferSize - 1) >> 4;
+                return 32 - (int)Lzcnt.LeadingZeroCount(bits);
+            }
 
             // bufferSize of 0 will underflow here, causing a huge
             // index which the caller will discard because it is not