c# - 64 位上按位和长整数与整数的性能

标签 c# .net

似乎在两个 long 之间执行 & 操作时,它花费的时间与 4 个 32bit int 中的等效操作花费的时间相同>s.

例如

long1 & long2

只要

int1 & int2
int3 & int4

这在 64 位操作系统上运行并面向 64 位 .net。

理论上,这应该快两倍。有没有人以前遇到过这个?

编辑

作为简化,假设我有两批 64 位数据。我将这 64 位放入 long 中,然后对这两个位执行按位 &

我也取了那两组数据,并将 64 位放入两个 32 位 int 值并执行 两个 &。我希望看到 long & 操作比 int & 操作运行得更快。

最佳答案

我无法重现问题。

我的测试如下(显示的是 int 版本):

// deliberately made hard to optimise without whole program optimisation
public static int[] data = new int[1000000]; // long[] when testing long

// I happened to have a winforms app open, feel free to make this a console app..
private void button1_Click(object sender, EventArgs e)
{
    long best = long.MaxValue;
    for (int j = 0; j < 1000; j++)
    {
        Stopwatch timer = Stopwatch.StartNew();
        int a1 = ~0, b1 = 0x55555555, c1 = 0x12345678; // varies: see below
        int a2 = ~0, b2 = 0x55555555, c2 = 0x12345678;
        int[] d = data; // long[] when testing long
        for (int i = 0; i < d.Length; i++)
        {
            int v = d[i]; // long when testing long, see below
            a1 &= v; a2 &= v;
            b1 &= v; b2 &= v;
            c1 &= v; c2 &= v;
        }
        // don't average times: we want the result with minimal context switching
        best = Math.Min(best, timer.ElapsedTicks); 
        button1.Text = best.ToString() + ":" + (a1 + a2 + b1 + b2 + c1 + c2).ToString("X8");
    }
}

为了测试 long a1a2 等被合并,给出:

long a = ~0, b = 0x5555555555555555, c = 0x1234567812345678;

在我的笔记本电脑 (i7 Q720) 上运行这两个程序作为 VS (.NET 4.5) 的发布版本 外部 我得到了以下时间:

整数: 2238,长整数: 1924

现在考虑到有大量的循环开销,而且 long 版本处理两倍的数据(8mb 对 4mb),它仍然明显领先。所以我没有理由相信 C# 没有充分利用处理器的 64 位位。

但我们真的不应该首先将其搁置。如果有问题,只需检查 jited 代码(调试 -> Windows -> 反汇编)。确保编译器使用您期望它使用的指令,然后继续。

尝试在您的处理器上测量这些单独指令的性能(这很可能特定于您的处理器型号)而不是汇编程序是一个非常糟糕的主意 - 而且从像 C# 这样的 jit 编译语言中,除了徒劳之外.但无论如何都没有必要,因为如果您需要知道,一切都在 Intel's optimisation handbook 中。

为此,这里是 x64 上程序的 long 版本的 a &= 的反汇编(发布,但在调试器内部 - 不确定这是否会影响组装,但它肯定会影响性能):

00000111  mov         rcx,qword ptr [rsp+60h] ; a &= v
00000116  mov         rax,qword ptr [rsp+38h] 
0000011b  and         rax,rcx 
0000011e  mov         qword ptr [rsp+38h],rax 

如您所见,有一个 64 位和预期的操作,以及三个 64 位移动。到目前为止一切顺利,并且恰好是 int 版本的操作数的一半:

00000122  mov         ecx,dword ptr [rsp+5Ch] ; a1 &= v
00000126  mov         eax,dword ptr [rsp+38h] 
0000012a  and         eax,ecx 
0000012c  mov         dword ptr [rsp+38h],eax 
00000130  mov         ecx,dword ptr [rsp+5Ch] ; a2 &= v
00000134  mov         eax,dword ptr [rsp+44h] 
00000138  and         eax,ecx 
0000013a  mov         dword ptr [rsp+44h],eax 

我只能得出结论,您看到的问题是特定于您的测试套件、构建选项、处理器...或者很可能,& 不是重点你相信它的论点。 HTH.

关于c# - 64 位上按位和长整数与整数的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8571034/

相关文章:

c# - Xamarin.Forms - 标签 FontSize OnPlatform - XAML 错误

.net - 可编辑的组合框,绑定(bind)到不在列表中的值

c# - 组合一个字符常量和一个字符串文字来创建另一个常量

c# - 给定一个整数数组,如何找到最大数的所有公倍数?

.net - 无法通过arm模板部署azure功能应用程序

c# - 将 Uploadify 与 Sharepoint 和 .net 结合使用

.net - System.Net 套接字非常奇怪的自发断开连接

c# - 捕获 DirectX 应用程序的视觉输出 - 即使在后台?

c# - 不能将 null 值分配给类型为 System.Boolean 的成员,该类型是不可为 null 的值类型

c# - 以编程方式使用备份数据库