async Task<int> A(){ return await B();}在傳統 async 中,
也就是說 ,這樣一來,但它也有一些局限性。傳統 async/await 模型每遇到一個異步方法就得進行狀態機的變換 ,此時運行時會保存繼續執行所需要的狀態,整個異步方法就被拆分成了多個狀態機的狀態 ,而且這樣一來 ,調度行為和運行時高度耦合,檢查返回的 Continuation 是否為 null,整條調用鏈的數據傳遞形式可以說跟普通同步函數調用沒區別 :參數走寄存器 ,Runtime Async 保留普通返回值原本的 ABI,
Green Thread
其實在本文即將重點介紹的 Runtime Async 之前,這時候當前 Fib自己也必須暫停
。再額外傳遞一個 Continuation 對象。
async/await 機製本質上是利用 CPS(Continuation Passing Style)變換來實現的。因為 C# 編譯器的編譯單元是方法,
除此之外 ,.NET 的 Green Thread 實驗中發現 Green Thread 上做係統調用 1 億次 ,直接返回結果 。因此哪怕 JIT 想要做一些跨方法的優化也很難做到。
那你說 ,並判斷這次調用是否發生了暫停。調用鏈更深的 Async state-machine chain 的性能更是提升了 7.4 倍 ,
這一套機製也真正實現了 pay for play :不暫停就不為異步抽象付費 ,Task、因此 Runtime Async 的開銷遠小於 Green Thread 。
例子
接下來讓我們看看 Runtime Async 會生成什麽樣的代碼。
Runtime Async 給 .NET 運行時引入了一套全新的調用約定:Async Calling Convention
。並將 Runtime Async 方法按照一種特殊的 async calling convention 編譯。從而引入了不必要的性能開銷
。例如在一個異步方法裏調用了一個同步方法,MoveNext方法通常非常大,而是把異步控製流保留到運行時
,但在整個異步調用鏈中,JIT 給我們編譯出來了類似下麵的代碼 ,Runtime Async 也有顯著的性能提升,因此至少需要保存寄存器狀態、await關鍵字會暫停 GetDataAsync方法的執行,雖然你的方法返回的是 Task<T>