.NET(C#):MethodImplOptions.NoInlining來阻止JIT內聯方法

來源:互聯網
上載者:User

眾所周知,引用程式集的載入並不是在程式開始運行時就全部載入的,CLR會載入相應的程式集當該程式集的類型被第一次使用。更具體的說,當一個方法被JIT時,CLR會確保該方法中的類型所在的程式集被載入。

 

比如我們的主程式Mgen.exe引用一個類庫ClassLibrary1,後者有一個類型Class1:

 

這段代碼,分別在使用ClassLibrary1的一個類型之前和之後對當前應用程式定義域載入的程式集進行枚舉:

static void Main()

{

    foreach (var ass in AppDomain.CurrentDomain.GetAssemblies())

        Console.WriteLine(ass.GetName().Name);

 

    Console.WriteLine("=== 分割線 ===");

 

    //使用ClassLibrary1的類型

    doo();

 

    foreach (var ass in AppDomain.CurrentDomain.GetAssemblies())

        Console.WriteLine(ass.GetName().Name);

 

}

 

static void doo()

{

    var obj = new ClassLibrary1.Class1();

}

 

運行代碼(注意要在Release發布模式),程式會輸出:

mscorlib

Mgen

ClassLibrary1

=== 分割線 ===

mscorlib

Mgen

ClassLibrary1

 

為何ClassLibrary1出現在第一個列表中?事實上如果JIT不對doo進行內聯處理的話,當Main方法被JIT後,CLR是不會覺察到Main方法會使用ClassLibrary1的,因此ClassLibrary1是不會出現在列表中的,但運行時刻JIT的最佳化使得doo被內聯在Main方法中,這樣整個代碼相當於:

static void Main()

{

    //省略

 

    //內聯的doo

    var obj = new ClassLibrary1.Class1();

 

    //省略

}

 

使用MethodImplOptions.NoInlining可以阻止JIT在編譯時間把某些方法進行內聯處理。注意MethodImpleOptions枚舉要用在MethodImpl特性上。(另外MethodImpleOptions枚舉還有其他功能,比如常見的MethodImpleOptions.Synchronized用來進行線程同步。可以參考MSDN:http://msdn.microsoft.com/zh-cn/library/system.runtime.compilerservices.methodimploptions.aspx)

最後注意上述類都在System.Runtime.CompilerServices命名空間內。

 

這樣的話在doo方法上加入MethodImpl特性:

//+ System.Runtime.CompilerServices;

[MethodImpl(MethodImplOptions.NoInlining)]

static void doo()

{

    var obj = new ClassLibrary1.Class1();

}

 

再次編譯整個程式,輸出:

mscorlib

Mgen

=== 分割線 ===

mscorlib

Mgen

ClassLibrary1

 

可以看到,此時由於doo沒有被內聯,JIT編譯Main方法後沒有發現使用其他程式集,所以第一次枚舉程式集沒有ClassLibrary1,而當doo方法真正執行後,更確切的說是在doo方法被JIT後,但在執行前,CLR會載入ClassLibrary1。所以第二次枚舉應用程式定義域中的程式集時,ClassLibrary1在列表中。

 

如果在Debug偵錯模式下運行程式,結果也是上面的輸出(ClassLibrary1不在列表1),因為偵錯模式下,JIT方法內聯最佳化是被禁止的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.