2011-07-13 59 views
7

我對GPU如何執行同步有一些疑問。 據我所知,當一個經紗遇到障礙(假設它在OpenCL中),並且它知道同一組的其他經紗尚未到達那裏。所以它必須等待。但在等待期間,這種扭曲究竟做了什麼? 它仍然是一個活躍的扭曲?或者它會做一些空操作?GPU中的同步

正如我注意到的,當我們在內核中進行同步時,指令的數量會增加。我不知道這個增量的來源是什麼。同步分解成許多更小的GPU指令嗎?或者因爲空轉經紗執行一些額外的指示?

最後,我非常想知道,與沒有同步功能(比如barrier(CLK_LOCAL_MEM_FENCE))相比,同步添加的成本是否受工作組(或線程塊)中的變形數量影響? 謝謝

回答

7

一個活動的warp是一個駐留在SM上的活動warp,即所有的資源(寄存器等)已經被分配,並且warp可用於執行,只要它是可調度的。如果一個warp在同一個threadblock/work-group中的其他warp之前到達屏障,它仍然是活動的(它仍然駐留在SM上,並且它的所有寄存器仍然有效),但是它不會執行任何指令,因爲它是沒有準備好安排。

插入一個屏障不僅阻止了執行,而且還作爲編譯器的屏障:編譯器不允許在屏障上執行最優化,因爲這可能會使屏障的用途失效。這是您看到更多指令的最可能原因 - 沒有編譯器能夠執行更多優化的障礙。

障礙的成本很大程度上取決於您的代碼正在做什麼,但是每個障礙都會引入一個泡泡,在所有經紗都必須(有效)變爲空閒狀態之前,它們都會再次開始工作,所以如果您有一個非常大的線程塊/工作組,那麼當然有一個可能比一個小塊更大的泡沫。這個泡泡的影響取決於你的代碼 - 如果你的代碼是非常受限於內存的,那麼這個屏障會在內存隱藏之前將內存延遲暴露出來,但是如果更加平衡的話,它可能會有不太明顯的效果。

這意味着,在一個非常內存限制的內核中,最好啓動大量更小的塊,以便當一個塊在屏障上冒泡時可以執行其他塊。您需要確保您的佔用率因此增加,並且如果您使用塊共享內存在線程之間共享數據,則需要進行折衷。

+0

感謝您的詳細解答。如果您可以分享您從中獲得知識的某些文檔,那將會很好。我想引用我的研究成果。你能解釋一下爲什麼內存綁定的內核會暴露內存延遲?正如我現在所理解的,一個同步附近的內存請求(出現在同步之前)應該被一些計算隱藏,直到數據到達時纔會停止。這是對的嗎?另一方面,如果內核不是內存綁定的,那麼同步會暴露什麼?指令流水線延遲? (沒有任何分歧,是的,這與分歧有什麼關係?) – Zk1001