从C#检查CPU Popcount

5

有人知道如何从C#检查CPU是否支持popcount(人口计数)吗?

我正在尝试将一些棋类代码从C++移植到C#。


在C++中,这需要一个特定于实现的编译器内置函数,例如__builtin_popcount(用于gcc)。 - Ben Voigt
3个回答

8
我尚未找到一种在C#中检测和使用特殊CPU指令的简单方法。有几个选项,但这些选项都不理想:
  • 使用asmjit函数进行popcount操作
  • 在C#中使用x86/x64 CPUID指令
  • mono库拥有数据类型支持的simd库(但我认为无法进行popcount操作)
  • 使用C++ DLL(可能会因为开销而慢得多)
  • ...

我从来没有走过这条路并且实现了一个C# popcount。

    /// <summary>
    /// Count the number of bits set to 1 in a ulong
    /// </summary>
    public static byte BitCount(this ulong value)
    {
        ulong result = value - ((value >> 1) & 0x5555555555555555UL);
        result = (result & 0x3333333333333333UL) + ((result >> 2) & 0x3333333333333333UL);
        return (byte)(unchecked(((result + (result >> 4)) & 0xF0F0F0F0F0F0F0FUL) * 0x101010101010101UL) >> 56);
    }

我不知道如果硬件popcnt不可用,BitOperations.PopCount会使用什么回退方法,但我希望它是那个众所周知的bithack。我假设这个答案是在BitOperations.PopCount出现之前写的(https://learn.microsoft.com/en-us/dotnet/api/system.numerics.bitoperations.popcount?view=net-7.0),因为那个应该至少和bithack一样好,而且希望更好。 - Peter Cordes

7

从.NET Core 3.0开始,您可以使用Popcnt.IsSupported来测试底层硬件的支持情况。

或者,如果您只需要结果,可以使用BitOperations.PopCount。在BitOperations类中的方法“在基础平台上可用硬件内部机制时使用;否则,它们使用优化的软件回退”。


3

由于C#编译为IL而不是机器码,因此您无法进行CPU级别的优化。通用语言运行时中的JIT编译器能够在实际运行代码时进行一些优化,但语言本身没有直接访问该过程的权限。

但是,您可以混合使用C++和托管代码,并在那里进行低级别的优化,但这有点违背了转向C#的初衷。


C#有很多支持CPU级别优化的功能。请查看Intrinsics和Vector支持。 - IvoTops
C#对于CPU级别的优化提供了很多支持。查看Intrinsics和Vector支持。 - IvoTops

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接