From b87ac1d65253ee5aea44c370e475542e056aa386 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Wed, 26 Dec 2018 18:03:36 +0000 Subject: [PATCH] Use PopCount intrinsic (#5715) --- .../Core/src/Internal/Http/HttpHeaders.cs | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs index ceb017ad28..3df0869931 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs @@ -6,6 +6,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics.X86; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.Extensions.Primitives; @@ -122,20 +123,29 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return StringValues.Concat(existing, append); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] protected static int BitCount(long value) { - // see https://github.com/dotnet/corefx/blob/5965fd3756bc9dd9c89a27621eb10c6931126de2/src/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs + int SoftwareFallback(ulong v) + { + // see https://github.com/dotnet/corefx/blob/5965fd3756bc9dd9c89a27621eb10c6931126de2/src/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs - const ulong Mask01010101 = 0x5555555555555555UL; - const ulong Mask00110011 = 0x3333333333333333UL; - const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; - const ulong Mask00000001 = 0x0101010101010101UL; + const ulong Mask01010101 = 0x5555555555555555UL; + const ulong Mask00110011 = 0x3333333333333333UL; + const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; + const ulong Mask00000001 = 0x0101010101010101UL; - var v = (ulong)value; + v = v - ((v >> 1) & Mask01010101); + v = (v & Mask00110011) + ((v >> 2) & Mask00110011); + return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); + } - v = v - ((v >> 1) & Mask01010101); - v = (v & Mask00110011) + ((v >> 2) & Mask00110011); - return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); + if (Popcnt.X64.IsSupported) + { + return (int)Popcnt.X64.PopCount((ulong)value); + } + + return SoftwareFallback((ulong)value); } protected virtual int GetCountFast()