我无法重现该问题。
我的测试结果如下(如图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");
}
}
为了测试多头a1
和a2
等合并,赠送:
long a = ~0, b = 0x5555555555555555, c = 0x1234567812345678;
运行在我的笔记本电脑两个方案(I7 Q720)作为发布构建VS(NET 4.5)的外部我得到以下时间:
INT:长: 1924年
现在考虑有一个巨大的循环开销的量,并且该long
版本正在与两倍的数据(8MB VS 4MB),它仍然出来明显领先。所以我没有理由相信C#没有充分利用处理器的64位bithop。
但是,我们真的不应该在一开始就改变它。如果有问题,只需检查jited代码(Debug - > Windows - > Disassembly)。确保编译器使用您期望使用的指令,然后继续。
尝试测量处理器上这些单独指令的性能(这可能是特定于处理器模型的),而汇编器以外的任何其他指令都是非常糟糕的想法 - 而且从C#等JIT编译语言中,超越徒劳的。但无论如何,因为它全部在Intel's optimisation handbook,所以你需要知道。
为此,这里的a &=
用于在x64的long
版本的程序的拆装(释放,但调试器内部的 - 不能确定这是否会影响组件,但它肯定会影响性能):
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
版本OPS的正好一半数量:
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。
“理论上,这应该快两倍” - 你基于什么?两者都将在相同的64位寄存器中完成,不是吗? – 2011-12-20 05:15:14
我很**怀疑你如何衡量这一点。我也认为这是一个相当疏忽,当提问有关你的计算机的64位性能的问题时不提及你的处理器... – Mania 2011-12-20 05:20:52
@Mitch - 好吧,如果我把一个long的内容分成两个int32s,那么它只需要一个&与2. – Khanzor 2011-12-20 05:27:11