2010-10-01 40 views
16

有一件事我沒有想出來,谷歌沒有幫助我,爲什麼有可能銀行與共享內存衝突,但不是在全球內存?銀行可以與寄存器衝突嗎?爲什麼Cuda/OpenCL在全局內存中沒有銀行衝突?

UPDATE 哇我真的很感謝Tibbit和灰熊的兩個答案。看來,我只能給一個綠色的複選標記一個答案,但。我對堆棧溢出很陌生。我想我必須選擇一個最好的答案。我可以做些什麼來表達謝意,我不給綠色檢查的答案嗎?

+0

您可以隨時給予好評的任何問題或答案你喜歡 – Grizzly 2010-10-04 18:47:31

+0

銀行的衝突可以在存儲器層次結構的其他級別以及寄存器文件發生。共享內存組衝突可以顯着影響內核性能,並且完全由開發人員控制。其他類型的銀行衝突對性能影響較小,開發人員無法解決,因此無法與開發人員溝通。 – 2012-11-28 05:42:23

回答

32

簡短回答:在全局內存或寄存器中都沒有銀行衝突。

說明:

理解的關鍵原因是要把握操作的粒度。單個線程不訪問全局內存。全局內存訪問是「合併」的。由於全局內存太慢,塊內線程的任何訪問都被分組在一起,以儘可能少地向全局內存發出請求。

共享內存可以被線程同時訪問。當兩個線程嘗試訪問同一個銀行內的地址時,這會導致銀行衝突。

寄存器不能被任何線程訪問,除了分配給它的那個線程。由於您無法讀取或寫入我的寄存器,因此您無法阻止我訪問它們 - 因此,沒有任何銀行衝突。

誰能讀&寫信給全球內存?

Only blocks。一個線程可以訪問,但事務將在塊級別進行處理(實際上是warp/half warp級別,但我不會變得複雜)。如果兩個模塊訪問相同的內存,我認爲這不會花費更長的時間,並且最新設備中的L1緩存可能會加速它 - 儘管這並不明顯。

誰可以閱讀&寫入共享內存?

Any thread within a given block.如果你只有每塊1線你不能有一個銀行的衝突,但你不會有合理的性能。發生銀行衝突是因爲一個塊被分配了幾個線程,比如說512個線程,並且它們都在同一個銀行內尋找不同的地址(不完全相同的地址)。在CUDA C編程指南 - 圖G2,第167頁(實際上是pdf的第177頁)結尾處,有一些這些衝突的優秀圖片。 Link to version 3.2

誰可以閱讀&寫入寄存器?

Only the specific thread to which it is allocated.因此,一次只有一個線程正在訪問它。

+0

注意,我對L1緩存的評論實際上是我自己的問題 - 確實發生在L1緩存銀行衝突。由於這完全是在硬件中處理的,我不相信我們在最新的文檔中被告知。 (但L1僅在最新的2. *硬件 - 所以如果你沒有費米GPU,這點它靜音)。 – 2010-10-02 19:54:43

22

在給定類型的內存中是否可能存在bank衝突顯然取決於內存結構及其目的。

那麼,爲什麼共享內存設計的方式允許銀行衝突呢?

這相對簡單,它不容易設計一個內存控制器,它可以同時處理對同一內存的獨立訪問(事實證明,大多數不能)。因此,爲了讓每個線程都能夠訪問一個單獨的地址單詞,內存就被存儲起來了,每個銀行都有一個獨立的控制器(至少這是怎麼想的,不知道實際的硬件)。這些銀行交錯使順序線程快速訪問順序存儲器。因此,每個銀行都可以同時處理一個請求,理想情況下允許在半war中同時執行所有請求(顯然,由於這些銀行的獨立性,這個模型在理論上可以維持更高的帶寬,這也是一個優點)。

寄存器怎麼樣?

寄存器設計爲作爲ALU指令的操作數訪問,這意味着它們必須以非常低的延遲進行訪問。因此他們可以獲得更多的晶體管/位來實現這一點。我不確定在現代處理器中訪問的是完全相同的寄存器(不是那種經常需要的信息,也不容易找到)。然而,在銀行中組織寄存器顯然是非常不現實的(對於更簡單的架構,您通常會看到所有寄存器掛在一個大的多路複用器上)。所以不會,寄存器不會有銀行衝突。

全局內存

首先全局內存的工作在不同的granuality然後共享內存。內存以32,64或128byte塊訪問(對於GT200,至少對於Fermi來說,它始終是128B,但緩存,AMD有點不同),每次你想從塊中獲得某些東西時,訪問/傳輸整個塊。這就是爲什麼你需要合併訪問的原因,因爲如果每個線程從不同的塊訪問內存,你必須傳輸所有的塊。

但誰說沒有銀行衝突?我並不完全確定這一點,因爲我還沒有發現任何實際的資源來支持NVIDIA硬件,但它似乎是合乎邏輯的: 全球存儲器通常分配給幾個RAM芯片(可以通過查看一個圖形卡)。如果這些芯片中的每一個都像本地存儲器銀行一樣,那麼如果在同一個銀行上有多個同時發生的請求,就會發生銀行衝突。然而,對於一件事情,這種影響會少得多(因爲內存訪問所消耗的大部分時間是無論如何都會將數據從A傳輸到B的延遲),並且它不會在一個工作組內「不可見」 (因爲一次只有一個半warp執行,如果這個halfwarp發出的請求多於一個,那麼你有一個不合並的內存訪問,所以你已經受到一次衝擊,很難測量這個衝突的影響。所以你只會遇到衝突幾個工作組試圖訪問同一個銀行在你典型的gpgpu情況下,你有一個大的數據集位於順序存儲器中,所以這些影響不應該是真的不可見的,因爲有足夠的其他工作組同時訪問其他銀行,但它應該可以構建數據集中僅存在於少數幾家銀行的情況,這會造成對帶寬的衝擊(因爲最大帶寬將來自所有銀行的平均分配接入,所以每家銀行都會只有該帶寬的一小部分)。再次,我沒有看過任何證明nvidia硬件理論的東西(大多數情況下都集中在合併,當然這更重要,因爲它使得自然數據集成爲非問題)。然而,根據ATI Stream計算指南,這是Radeon卡的情況(對於5xxx:銀行間隔2kb,並且您希望確保您在所有銀行中均勻分配您的訪問(意味着來自所有模擬活動的worgroups)),所以我會想象NVidia卡的行爲是相似的。

當然對於大多數scenarious全球記憶體衝突的可能性是一個非的問題,因此在實踐中,你可以說:

  • 手錶合併訪問全局內存
  • 關注銀行時發生衝突時,訪問本地內存
  • 沒有問題訪問寄存器
+0

也注意全球記憶露營的分區! – mch 2010-10-06 22:40:29

+1

尋找在分區露營的信息,我一頭栽進這個答案。你說得對,全局內存物理分區中分成,而一些訪問模式甚至可能產生衝突時,訪問被合併(查看關於矩陣的文檔轉的CUDA SDK例子)。然而,在費米架構和一般用於與計算能力2.x設備,全球存儲器訪問高速緩存,32字節的寬度,和地址被散列,所以理論上分區露營不應該是一個問題。 – Auron 2012-07-18 10:07:28

+0

不要在內存架構,這些改進計算能力> = 2.0還減少分區露營爲全球內存的影響*寫*? – 2012-12-07 15:22:44

3

多個線程訪問相同的銀行並不一定意味着存在銀行股份有限公司nflict。如果線程想同時從同一個銀行內的不同行讀取,則會發生衝突。