我無法重現該問題。
我的測試結果如下(如圖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