如2個計算結果,a=3.14……,b=3.15……,要判斷a、b大小,在GPU中判斷,還是給CPU判斷?


if是branch,你要做的「比較大小」的操作是cmp,不是一回事。


如果只是比較數據大小,cpu的latency通常低一些,gpu因為是simt/simd,要對更多數據同時運算,所以latency通常會稍高。

當然nv的turing已經做到常見簡單指令4cycle,和cpu不差太多了。但是考慮到主頻的話,時間上還是cpu快。

不過如果按吞吐率去算單位操作的耗時的話,gpu更快不用說。


至於if這種真branch(指asm層面真的發生了branch,而不是cmov/csel這種),cpu有分支預測+投機執行,所以可能能0開銷。

gpu的話一次性多個thread鎖步執行,branch可能只是更新一下mask,按道理開銷也不會很大。

但是gpu可能要保存stack信息(以後reconverge用),也可能要對各種依賴做同步(寄存器依賴、scoreboard),所以可能開銷更大。

而多個線程diverge的話,兩側分支都要走一遍,相當於在線程角度做csel,不太好和cpu的做法直接比較。


再說了,你如果想拿gpu做這麼一個操作,你得先傳數據給gpu,調用驅動配置gpu,然後髮指令讓gpu執行,然後等執行完了還要傳數據回來,這個延遲夠cpu做幾萬次branch了…

結論:問題問得沒意義,回答也答得挺沒意義的。


gpu當然可以執行if,只不過和cpu有些區別。

cpu程序邏輯上就是一個線程,分支就是跳轉到別的位置。gpu由於是多個線程同時執行,在沒有分支時,一般warp內各個線程執行相同指令,有分支時會出現部分線程跳轉,部分線程不跳轉的情況,gpu能正確處理這些情況,不過效率不一定高,gpu分支執行這塊在學術界和工業界有不少研究,幾乎每一代的gpu都在這部分做了不少優化和提升,比如nvidia volta架構這部分改動就比較大。


當前的GPU,基本上都是SIMD架構。SIMD,顧名思義,一個block中的多個ALU同時執行一條相同的指令,但是是對不同的數據進行操作。假設一個block有8個ALU,從GPU的角度來看,希望8個ALU處理的數據在內存中是相鄰存儲的。這樣,GPU從內存中讀取數據時,通過連續的burst,一次性將數據讀取進入GPU內部。然後,8個ALU一次性將這些數據並行處理完成,從而達到GPU的最高性能。

對於CPU,在計算if 後面的條件後,根據條件執行if分支,或者else分支。CPU通常還有強大的分支預測和亂序執行的邏輯,支持程序高效的執行。對於SIMD的GPU,如果遇到if else語句,如何執行?GPU則沒有分支預測,也無法亂序執行。GPU遇到if else語句後,將按照順序執行if分支,然後執行else分支。最後,根據if後面的條件計算結果,選擇保留if分支或else分支的結果。就像下面的圖一樣(網上摘圖,侵權刪除)

所以,GPU代碼裡面盡量避免if else語句。當然Nvidia也一直在優化這個處理。


這種簡單的語句他們都可以做。CPU的特色是幾個複雜的核心,做複雜的事情。GPU就是大量簡單的核心,大量做簡單的事情。各有優勢而已。

比如你有一個64核128線程的線程撕裂者CPU(AMD Yes),純CPU渲染LOL之類的遊戲,也是蠻流暢的。


這還真回答不了,只好側面回答一下。

注意x86的浮點運算是在浮點運算器中執行的,而浮點運算單元是有個狀態寄存器的,用來表示執行結果的狀態,而這個狀態是cpu可以用來干if這件事的,比如可以測試該寄存器的一些位,然後jmp 到別的地址,執行其它指令序列。

而gpu寄存器和指令長啥樣cpu是不知道的,只能讀寫特定埠,其實就是一些特定地址單元,來控制gpu。那麼gpu 有沒有相應的狀態寄存器和測試指令呢?肯定是有的,但只有製造商自己清楚,從來沒見過gpu 的技術手冊。但intel的cpu技術手冊有幾千頁,從官網隨便下載。

所以gpu 驅動就是製造商自己寫,還能打雞血。大家一起罵—為什麼不開源?而指令效率問題,這真回答不了,答的都是靠猜。


推薦閱讀:
相关文章