Use PopCount intrinsic (#5715)
This commit is contained in:
parent
4d0ff9967a
commit
b87ac1d652
|
|
@ -6,6 +6,7 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.Intrinsics.X86;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
|
|
@ -122,20 +123,29 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||||
return StringValues.Concat(existing, append);
|
return StringValues.Concat(existing, append);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
protected static int BitCount(long value)
|
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 Mask01010101 = 0x5555555555555555UL;
|
||||||
const ulong Mask00110011 = 0x3333333333333333UL;
|
const ulong Mask00110011 = 0x3333333333333333UL;
|
||||||
const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL;
|
const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL;
|
||||||
const ulong Mask00000001 = 0x0101010101010101UL;
|
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);
|
if (Popcnt.X64.IsSupported)
|
||||||
v = (v & Mask00110011) + ((v >> 2) & Mask00110011);
|
{
|
||||||
return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56);
|
return (int)Popcnt.X64.PopCount((ulong)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SoftwareFallback((ulong)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual int GetCountFast()
|
protected virtual int GetCountFast()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue