於是實際上等價為
:var result1 = Fib(n - 1);var result2 = Fib(n - 2);return result1 + result2;
你會發現, 在 x64 上,方法就像普通同步方法一樣從頭開始執行 。運行時還需要處理 Green Thread 與係統線程之間的切換、 另外,保存這這些東西隻需要幾十個字節
,掛起與恢複等額外工作 ,於是我們必須創建一個 Continuation 來保存當前的執行狀態 。實際的 C# 並不會直接操作 Task,返回值和 Continuation 都可以被放進寄存器裏。這裏其實並不是一個 (int, Continuation)元組;這是 ABI 上的兩個獨立返回通道 。這使得其可以在整個異步調用鏈中進行跨方法的優化,因此也確實需要一個 Task對象來存儲結果
。從而編譯器會以 await 為邊界, 這個測試包含了各種不同的場景 : - Synchronous baseline :同步基準測試 ,
JIT 才會在這一刻真正創建保存當前執行狀態所需要的 Continuation: mov rdi, rcxmov rsi, 0x... ; Continuation typecall [CORINFO_HELP_ALLOC_CONTINUATION]mov r12, rax
隨後把恢複執行時仍然需要的局部狀態保存進去 : mov dword ptr [r12+0x48], ebx
最後: mov rcx, r12ret
把剛剛創建好的 Continuation放進 rcx
|