5

Does anyone know how to check from C# whether the CPU supports popcount (population count)?

I'm trying to port some chess code from C++ to C#.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
David
  • 131
  • 3
  • 6
  • In C++, this requires an implementation-specific compiler intrinsic, e.g. `__builtin_popcount` (for gcc). – Ben Voigt May 23 '11 at 13:49

3 Answers3

8

I have yet to find an easy way to detect and use special CPU instructions in C#. There are several options, none of them nice;

  • asmjit a function that does popcount
  • x86/x64 CPUID in C#
  • mono has a simd library with datatype support (not popcount I guess)
  • Use a C++ DLL (probably way slower because of overhead)
  • ..

I never went that way and implemented a 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);
    }
Community
  • 1
  • 1
IvoTops
  • 3,463
  • 17
  • 18
  • IDK what fallback `BitOperations.PopCount` uses if hardware `popcnt` isn't available, but I'd hope it's that well-known bithack. I assume this answer was written before `BitOperations.PopCount` existed (https://learn.microsoft.com/en-us/dotnet/api/system.numerics.bitoperations.popcount?view=net-7.0), since that's hopefully always at least as good as a bithack, and hopefully better. – Peter Cordes May 23 '23 at 02:56
7

Starting in .NET Core 3.0, you can use Popcnt.IsSupported to test for the underlying hardware support.

Or, if you just need the result, use BitOperations.PopCount. The methods in the BitOperations class "use hardware intrinsics when available on the underlying platform; otherwise, they use optimized software fallbacks".

Bradley Grainger
  • 27,458
  • 4
  • 91
  • 108
3

Since C# is compiled to IL not to machine code, you cant really do CPU level optimizations. The JIT compiler in the common language runtime is able to do some optimization when the code is actually run, but there is no direct access to that process from the language itself.

You can however mix C++ and managed code and do your low level optimizations there, but it kind of defeats the purpose of moving to C#.

TylerH
  • 20,799
  • 66
  • 75
  • 101
aL3891
  • 6,205
  • 3
  • 33
  • 37
  • C# has lots of support for CPU level optimizations. Check out the Intrinsics and Vector support. – IvoTops May 23 '23 at 16:48