2011-09-02 69 views
11

Does .NET JIT optimize empty loops away?的跟進:有沒有辦法讓.Net JIT或C#編譯器優化空的for-loops?

以下程序只運行一個空循環十億次並打印出運行時間。我的機器需要700毫秒,我很好奇是否有辦法讓抖動優化空白循環。

using System; 

namespace ConsoleApplication1 { 
    class Program { 
     static void Main() { 
      var start = DateTime.Now; 
      for (var i = 0; i < 1000000000; i++) {} 
      Console.WriteLine((DateTime.Now - start).TotalMilliseconds); 
     } 
    } 
} 

至於我可以告訴答案是否定的,但我不知道是否有可能是我試圖隱藏的編譯器選項。我已經確保在發佈模式下編譯並且在沒有附加調試器的情況下運行,但仍然需要700 ms來運行這個空循環。我也嘗試過NGEN,結果相同(儘管我的理解是它應該產生與JIT相同的編譯代碼,對吧?)。不過,我以前從未使用過NGEN,可能會錯誤地使用它。

似乎這樣會是這樣容易使JIT發現和優化掉,但是瞭解甚少抖動一般是如何工作的,我很好奇,如果有這種優化將遭到冷落特殊原因。此外,VC++編譯器似乎確實做了這種優化,所以我想知道爲什麼這種差異。有任何想法嗎?

+6

爲什麼在現實中這是一個問題?如果你有一個空的循環,只是擺脫它。 –

+0

這與您所引用的問題有何不同? –

+0

@Reed我知道java有JIT選項,如服務器和客戶端。參考問題不會詢問任何可能會調節抖動的選項,以優化此選項。 –

回答

7

不,我知道的任何.NET抖動都不會清空for循環。確切的原因對我來說並不那麼清楚,抖動優化器當然知道如何進行優化,並且很容易消除死代碼。詳情請查詢this answer。我相信這是有意爲之,因爲它可能有預期的副作用而留下循環,耗費時間。當然,對於實現spinwait的非常短的循環來說,這當然是有意義的。

+3

雖然這是一種奇怪的邏輯。優化代碼的關鍵在於讓它消耗更少的時間。如果您決定保留花費的時間,這種做法會削弱整個優化的想法。 – jalf

+4

spinwait是一個優化。 –

+0

看到空循環讓我想起了使用空循環引入延遲或依靠CPU時序來加強編程速度的寫作不好的舊式DOS程序。運行真正舊遊戲的DOS模擬器有時必須有意限制CPU執行,以便遊戲不會以可笑的幀率更新。 –