Branch Prediction 與 Branch Predication的區別

來源:互聯網
上載者:User

    Branch Prediction和Branch Predication都是針對程式分支語句影響硬體執行效率而提出的技術。Branch Prediction應用於CPU,目標是保證最高的線程執行效率。Branch Predication應用於SPMD結構的運算裝置,這類裝置以輸送量為首要目標,GPU就是這類裝置的代表。

Branch Prediction

    Branch Prediction,即分支預測,目的是保證大部分時間下CPU流水線都處於滿負荷狀態,保證正在執行的線程以最高效率運行。CPU流水線可大致劃分為4個階段:指令預取、指令解碼、執行和結果回寫。當程式碼出現條件分支語句時,條件分支語句的下條指令直到條件結果計算完畢後才能確定。在結果計算完畢前,CPU流水線都無法進行指令預取和指令解碼(這是因為無法確定下一條指令),也就是流水線stall了。為瞭解決流水線stall,提升執行效率,CPU的分支預測硬體模組在條件結果計算完畢前,根據程式的曆史運行記錄,預判下一條指令的位置並將其應用於流水線。如果條件結果計算符合預期或者說預判正確,CPU的流水線就不會stall,執行效率最高。

    如果CPU不引入分支預測,那麼,條件分支語句的執行效率永遠是最低(因為流水線必然stall),引入分支預測後,CPU流水線就會有一定幾率不stall,提升了執行效率,特別地,當程式編寫時有意迎合CPU分支預測機制,那麼程式就能高效的執行,例如對一個int數組內大於100的元素進行操作,那麼一個已排序的數組跟一個沒有排序的數組執行相同的代碼,執行效率顯然是已排序數組的情況下高。下面是虛擬碼:

for (int i in IntArray)

{

    if (i > 100)

    {

        // do 

    }

}

當這段代碼應用於已排序的數組時,CPU分支預測失敗的情況(也就是說流水線stall)可能只發在i滿足大於100這個條件的前幾次迴圈裡,而大部分時間,CPU的流水線都是滿載運行。如果數組沒有排序,CPU分支預測失敗的情況就會很普遍,代碼的運行效率就會下降。

最後,分支預測需要硬體模組的支援,所以必然會提升硬體複雜度和功耗。

Branch Predication

    首先解析SPMD及對應的硬體結構。SPMD就是Single Program Multiple Data,可以理解為SIMD的擴充。在SIMD情況下,對多資料的處理只限於單條指令,而SPMD情況下,程式編寫者可以按需要編寫一個處理多資料的程式,這個程式在多個線程中並存執行。GPU的Shader程式就是SPMD的一個例子。

    硬體結構上,將多個ALU綁定一起,共用一個PC(Program Counter),就能組成一個SPMD運算單元,例如NV GPU的SMX,AMD GPU的CU都是SPMD運算單元。一個SPMD運算單元包含的ALU數量決定了線程的理論最大並行數量。為了簡化硬體結構,降低功耗,SPMD運算單元並沒有為每個ALU配備分支預測硬體模組,更重要的是,在共用PC前提下,為每個ALU配備分支預測硬體模組對執行效率根本沒有任何提升。

    條件分支的出現將導致SPMD運算單元內ALU的執行路徑不一致。由於這些ALU共用同一個PC,所以,要求ALU並存執行不同路徑是不可能的。要在SPMD上實現條件分支,就需要編譯器對條件分支程式碼進行等價變換,把不一致的執行路徑轉換成一致的執行路徑,看下面這個例子:

A.原始代碼,執行路徑不一致

int condition = threadid + 100;

int result = 0;

if (condition > 220)

{

    result += 10;

}

else

{

    result -= 10

}

B.一種可能的轉換後的代碼

int result = 0;

int condition = threadid + 100;

int temp1 = result + 10;

int temp2 = result - 10;

result = (condition > 220) ? temp1 : temp2;

轉換後的代碼在每個ALU上的執行路徑都一致,不存在條件分支。兩個分支都執行,根據條件選擇接受哪個分支的結果,就叫Branch Predication分支斷定。

    Branch Predication需要硬體指令集的支援,支援Branch Predication的指令根據某些狀態寄存器的值,執行不一樣的邏輯,例如x86的cmov系列指令,又例如某些廠商GPU指令會根據狀態寄存器的值選擇執行還是NOP(傳說中的指令級多態?)。

    使用Branch Predication轉換後的代碼,執行時間比條件分支代碼長,因為轉換後的代碼,所有分支都會執行。於是,有人提出了一種類似動態指令融合的技術,在SPMD裡既可保留條件分支,也保證執行效率——Dynamic warp formation。

Dynamic warp formation

    Warp就是線程組threadgroup的意思,是SPMD運算單元的最小並行粒度,最小調度單位(NV稱為warp,AMD稱為wavefront)。例如,NV的warp為32線程,就是說,在SPMD運算單元內,每32個ALU並存執行相同的指令。也可以把warp看作是一條硬體執行緒,它的執行寬度為32個ALU。相對於CPU的線程,其執行寬度通常為1個ALU。當然了,GPU一個ALU的寬度可達4*64 bit,那麼,GPU一個warp的寬度就是32*4*64 bit,並且,GPU在同一時間可執行多個warp,所以單比輸送量,GPU與CPU不在一個數量級。

    以下均使用warp表示線程組,並以32線程為一個warp為前提展開。回顧SPMD出現條件分支的情況,例如出現分支A及分支B,那麼,warp內32個線程既執行分支A也執行分支B,最後,這些線程根據分支條件的結果選擇接受A的結果還是接受B的結果。無論如何,總有一部分結果對於這些線程來說是沒有意義的。

    把一個warp按分支路徑拆分成多個子warp,並存執行,也不會帶來任何效率的提升,因為拆分的子warp寬度肯定不夠32。如果把這種思路應用於多個warp的話,情況會有所不同,例如warp1,warp2和warp3執行相同的代碼併到達相同條件分支語句,分支將產生路徑A和路徑B,按路徑拆分出的子warp重組成新warp並存執行,分支路徑執行完畢後還原為原來的warp,這樣就能高效應對條件分支,不會出現沒有意義的運算,這就是Dynamic warp formation,更詳細的介紹可自行google。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.