是不是GPU和DSP進行邏輯判斷要比CPU慢?
因為聽過這個說法很多遍,工作中盡量避免在GPU的shader語句中寫邏輯判斷語句。但一直不明白究竟是什麼原因導致了GPU還有DSP進行邏輯判斷要比CPU慢?是因為它們負責邏輯運算的單元比CPU性能弱嗎?或者說在GPU或DSP代碼中增加一條if語句對性能的影響要大於CPU代碼中增加一條if語句的情況?
不是因為if本身,而是因為GPU的執行方式。
你可以這麼認為。GPU上面有很多很多硬體線程。基本執行單元不是一個線程,而是一組線程之間SIMD。對於shader來說,在有些硬體上,相鄰4x4的pixel被分為一組,而這一組都要執行同樣的指令。所以他們之間如果有的走了if,有的走了else,就需要兩個分支都執行,之後再根據條件取一個需要的結果。但如果都走的同樣的分支,那麼這個if就是幾乎無開銷的。當程序中包含分支語句而且判斷條件的值只有到了運行時才能知道的時候,硬體必須負責決定邏輯判斷的結果,即程序的控制流將轉向哪裡。目前的處理器大多採用流水線方式處理運行指令,這意味著前一條語句沒有執行完,後一條語句已經開始執行了。假如前一條語句是計算判斷條件的值,後一條語句是分支語句,那麼後一條語句必須等前一條語句執行完(即得到判斷條件的結果)才能繼續執行。也就是說,流水線必須暫停,等待前一條語句執行結構才能繼續運轉。這就是分支語句造成程序性能下降的主要原因。
CPU的設計目標是優化單線程延遲,即單一線程從開始到結束的執行時間。CPU包含很多優化機制來減少上面提到的分支開銷,減少由分支帶來的流水線空閑周期。主要技術包括分支預測(branch prediction)和猜測執行(speculative execution)等。這些技術的目的都是儘快得到判斷條件的結果,以得知分支到底轉向哪裡。
GPU的設計目標是優化多線程吞吐量,即一定時間內有多少線程能夠完成。GPU不關心單一線程執行的快慢與否(事實上,GPU單線程要比CPU單線程慢很多)。因此,當前的GPU把大量的晶元面積用於計算部件,取消分支預測和猜測執行等複雜的又占晶元面積的微體系結構部件,這就造成了流水線中可能存在分支開銷。當程序中分支條件越多時,帶來的分支開銷就越大。另外,GPU的執行方式與與CPU完全不一樣,GPU線程一批一批(即一個warp或者wavefront)的執行。一批線程是完全同步執行的,不可繼續劃分前半批先執行後半批後執行。當一批線程中需要分支時(如,前半批做加法,後半批做減法),GPU先用一批執行加法,然後扔掉後半批的結果,再用同一批執行減法,然後扔掉前半批的結果。也就是說,這種情況下,GPU的分支執行時間等於if和else之和,而不是像CPU那樣取決於if或者else的時間。
希望解答了樓主的疑惑。一般的分支,gpu確實可能效率低一些,即很多文檔提到的warp divergence問題。但是沒有divergence的分支,特殊情況下,我認為gpu反倒可以比cpu效率更高。
以cuda為例:
1. 普通的分支,一個warp內的32個線程如果分支不一致的話,兩個分支都會執行,每個分支執行的時候,一部分thread被mask掉了,這種情況確實比較低效。
2. 一個warp的32個線程的分支結果是一致的,這種情況,gpu上只會執行一個code path。僅僅如此的話,最多也就是和cpu效率一樣。但是gpu架構的一個特殊優勢是零開銷的warp scheduling,這一點保證gpu的分支不需要branch prediction,等待true/false判斷的時候,warp scheduler會直接換出當前warp,讓其他warp執行,硬體不會空閑。而cpu是依賴於branch prediction的,如果預測失敗,流水線裡面的東西就全都失效重來。這種情況下,cpu有效率損失,而gpu沒有。
這種情況發生的前提是:
1. 沒有warp divergence。
2. gpu有足夠的occupancy,保證等待true/false結果的時候,有足夠的其他warp可以佔用計算資源。
3. 如果在CPU上執行,這個分支的預測有一定的失敗概率。
GPU邏輯判斷並不慢,只是要每個分支都走一遍。除非某窩線程的條件恰好是一樣的,都只需要走一個分支。
推薦閱讀:
※如何看待「全球首起英偉達、AMD 粉絲暴力血案:一言不合11刀捅死對方」?
※手機的gpu能否如電腦主機布局一樣做成cpu,gpu做成獨立的,從而提升手機圖形處理能力?
※未來 GPU 在計算機領域的地位會越來越重嗎?
※VR的迅速發展是因為背後的GPU等技術發生了怎樣的變化?