2013-09-23 65 views
1

我寫了下面的Java測試通過Sandy-Bridge CPU進行優化?

public class NegativeTest { 

/** 
* @param args 
*/ 
public static void main(String[] args) { 

    long start = System.currentTimeMillis(); 

    int value = 12345; 
    for (int j = 0; j < 30; j++) { 
     for (int i = 0; i < 1000000000; i++) { 
      value = value * -1 - i; 
     } 
    } 

    System.out.println(System.currentTimeMillis() - start); 

    //to avoid compilation optimization 
    System.out.println(value); 
} 
} 

花了約1.3秒完成我的英特爾(R)酷睿(TM)i5-3210M(常春藤橋)機,但之後我改了行

值=值* -1 - I

值=值 - 我

然後花了大約10秒完成(大約是以前版本的10倍)!

當我跑到其他非的Sandy Bridge CPU的這個測試,結果是完全顛倒過來: 的值=值* -1 - 我版本需要兩倍長的值=價值 - 我版本並!

任何人都可以解釋這種差異?它與Sandy Bridge架構中的任何特定優化設計有關?

+0

那麼這很有趣。當我在C++中嘗試這個時,第一個情況是0秒,第二個是7.472秒。看起來,在第一種情況下,我的C++編譯器設法將循環完全優化爲單個值。所以這基本上歸結爲編譯器優化。也許Java JIT爲SB做了一些不同的事情。 (哦,我測試了它在Sandy Bridge機器上) – Mysticial

+0

@Mysticial你在非沙質橋式機器上嘗試過嗎? – njzhxf

+0

這沒關係。因爲我的C++編譯器將第一種情況優化爲基本'print(「 - 2115085767」)'。這將在任何處理器上零時間運行。 – Mysticial

回答

1

我曾嘗試在C#.NET 4.6的x64相同

1)現在16239ms

2)8175ms

如果我看上去拆卸DIFF:

1)

value = value * -1 - i; 
000007FE9958422A neg   edx 
000007FE9958422C sub   edx,eax 

2)

value = value - i; 
000007FE995842A2 sub   edi,eax 

我有一個i7 4790K。

如果我使用雙/漂浮的整數,而不是拆卸包含標AVX的代碼,這可能會更快:

value = value * -1 - i; 
000007FE9957422B vmulsd  xmm0,xmm0,mmword ptr [7FE99574298h] 
000007FE99574234 vcvtsi2sd xmm1,xmm1,eax 
000007FE99574239 vsubsd  xmm0,xmm0,xmm1 

所以現在這將是有趣的使用AVX 2.0整數。

編輯:

當我嘗試在C++,我得到0秒

其實這是曳:)

請注意標杆並不容易,你需要仔細看拆卸,使用精確的計數器,確保CPU不處於均衡能源模式,應用程序是最重要的,等等。