Skip to content

Commit

Permalink
Speedup SpanHelpers.IndexOf{Any}(byte, ...) (dotnet/coreclr#22118)
Browse files Browse the repository at this point in the history
* Speedup SpanHelpers.IndexOf(byte)

* 128 * 2 alignment

* Move TrailingZeroCountFallback to common SpanHelpers

So it can be used by other types than byte

* Speedup SpanHelpers.IndexOfAny(byte, ...)

* Indent for support flags

* More helpers, constency in local names/formatting, feedback

* Skip bounds check in software fallback

Signed-off-by: dotnet-bot <[email protected]>
  • Loading branch information
benaadams authored and dotnet-bot committed Jan 24, 2019
1 parent 7d3dc51 commit 2536d86
Show file tree
Hide file tree
Showing 4 changed files with 709 additions and 344 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\AttributeUsageAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\BadImageFormatException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\BitConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\BitOps.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Boolean.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ArrayPool.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ArrayPoolEventSource.cs" />
Expand Down
38 changes: 38 additions & 0 deletions netcore/System.Private.CoreLib/shared/System/BitOps.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;

using Internal.Runtime.CompilerServices;

namespace System
{
internal static class BitOps
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int TrailingZeroCount(int matches)
{
if (Bmi1.IsSupported)
{
return (int)Bmi1.TrailingZeroCount((uint)matches);
}
else // Software fallback
{
// https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
// uint.MaxValue >> 27 is always in range [0 - 31] so we use Unsafe.AddByteOffset to avoid bounds check
return Unsafe.AddByteOffset(
ref MemoryMarshal.GetReference(TrailingCountMultiplyDeBruijn),
((uint)((matches & -matches) * 0x077CB531U)) >> 27);
}
}

private static ReadOnlySpan<byte> TrailingCountMultiplyDeBruijn => new byte[32]
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
}
}
Loading

0 comments on commit 2536d86

Please sign in to comment.