Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance difference between AnyCPU vs x64 platform on a 64 bit machine

According to this QA there should be no performance difference between application built using Any CPU and x64 when run on a 64 bit machine, however I'm seeing around a double increase in performance in my use case when I specifically built for the x64 platform.

My use case is for manipulating 64 bit bitboards, the majority of processing is on bit operations and arithmetic on ulong variables.

As an example:

public static ulong ReverseBits(ulong x)
{
    ulong t;
    x = (x << 32) | (x >> 32); // Swap register halves.
    x = (x & 0x0001FFFF0001FFFFUL) << 15 | // Rotate left
        (x & 0xFFFE0000FFFE0000UL) >> 17; // 15.
    t = (x ^ (x >> 10)) & 0x003F801F003F801FUL;
    x = (t | (t << 10)) ^ x;
    t = (x ^ (x >> 4)) & 0x0E0384210E038421UL;
    x = (t | (t << 4)) ^ x;
    t = (x ^ (x >> 2)) & 0x2248884222488842UL;
    x = (t | (t << 2)) ^ x;
    return x;
}

static void Main(string[] args)
{
    ulong sum = 0;
    var s = Stopwatch.StartNew();
    for (ulong i = 0; i < 1000000000; i++)
    {
        sum += ReverseBits(i);
    }
    s.Stop();

    Console.WriteLine("Sum = {0}, took {1}ms", sum, s.ElapsedMilliseconds);
    Console.ReadLine();
}

In Release build with Any CPU platform the results are: Sum = 9745675244420464640, took 13148ms

In Release build with x64 platform the results are: Sum = 9745675244420464640, took 5693ms

That's more than double performance increase. Why is there such a big difference if the common assumption is that Any CPU vs x64 builds should perform the same on a 64 bit machine?

like image 816
Beyers Avatar asked Feb 05 '23 22:02

Beyers


1 Answers

No, you compared perf between 32-bit and 64-bit code. The x64 flavor is much faster because it can do the math with a single 64-bit processor register. It is much more of a slog in 32-bit machine code, it has to juggle two 32-bit registers. Easy to see the difference between the two with Debug > Windows > Disassembly.

This went wrong because you paid too much attention to the solution platform name. Too prominently displayed, but a selection that only matters to C++ projects. And, unfortunately, on UWP projects due to .NET Native. It selects the build tool flavors, C# has only one compiler that can target any platform.

The real settings that matters are the jitter forcing options. Project > Properties > Build tab. Select the Release build if necessary and choose the Platform target and "Prefer 32-bit" settings. Untick the latter. You'll now see that AnyCPU == x64 on a 64-bit operating system.

like image 145
Hans Passant Avatar answered Feb 08 '23 10:02

Hans Passant