2010-11-04 41 views
5

我翻閱了編程指南和最佳實踐指南,它提到全局內存訪問需要400-600個週期。我沒有看到像紋理緩存,常量緩存,共享內存等其他內存類型。寄存器有0個內存延遲。OpenCL/CUDA中每個內存訪問類型有多少內存延遲週期?

我認爲如果所有線程在常量緩存中使用相同的地址,常量緩存與寄存器相同。最壞的情況我不太確定。

只要沒有銀行衝突,共享內存與寄存器是相同的?如果有,那麼延遲如何展開?

紋理緩存怎麼樣?

回答

4

共享/常量/紋理存儲器的延遲很小,取決於您擁有的設備。通常,雖然GPU被設計爲吞吐量架構,這意味着通過創建足夠的線程,隱藏了包括全局內存在內的內存延遲。

指南中提到的全局存儲器延遲的原因是,延遲比其他存儲器的延遲高出幾個數量級,這意味着它是優化考慮的主要延遲。

您特別提到了常量緩存。如果一個warp(即32個線程的組)中的所有線程都訪問相同的地址,那麼就沒有懲罰,即從緩存中讀取值並同時向所有線程廣播,這是非常正確的。但是,如果線程訪問不同的地址,則訪問必須連續化,因爲緩存一次只能提供一個值。如果您使用的是CUDA Profiler,那麼這將顯示在序列化計數器下。

與常量緩存不同,共享內存可以提供更高的帶寬。查看CUDA Optimization討論,瞭解更多細節和銀行衝突及其影響的解釋。

+0

如果例如所有線程都訪問1000浮點數,它仍然值得使用常量緩存嗎?這是否會像一個1000從註冊表中讀取?該指南表示這種常量緩存的使用以這種方式線性擴展了嗎? – smuggledPancakes 2010-11-04 16:56:44

+0

如果所有線程在循環的任何給定迭代中訪問* same *值,則可以使用常量緩存。由於空間局部性,常量緩存將提供一些好處(在Fermi上,L1緩存可能達到同樣的效果,但這會使L1免費用於其他數據)。話雖如此,我主要針對費米,並且從不使用'__constant__',我只是使用const並讓編譯器弄清楚它!例如在你的情況下,我會將內核參數作爲'const float * const myfloatarray'來傳遞。我建議你總是運行Visual Profiler來檢查序列化,以防萬一你錯過了某些東西。 – Tom 2010-11-05 08:03:30

+0

有人可能會說,L1(L2)的高速緩存行爲128byte(32byte),所以我們討論的是地址落入相同的行(不一定是相同的地址)。有些其他延遲的數字可以在[這裏]找到(http://stackoverflow.com/questions/6744101/fermi-l2-cache-hit-latency)。 – 2012-09-09 15:03:52

6

對於(開普勒)特斯拉K20的延遲如下:

全局存儲器:440個時鐘
常量存儲器
        L1:48個時鐘
        L2:120時鐘
共享內存:48個時鐘
紋理內存
        L1:108個時鐘
        L2:240個時鐘

我怎麼知道?我運行了Demystifying GPU Microarchitecture through Microbenchmarking的作者描述的微基準。它們爲舊版GTX 280提供了類似的結果。

這是在Linux羣集上測量的,我運行基準測試的計算節點沒有被任何其他用戶使用或運行任何其他進程。它是BULLX linux,帶有一對8核Xeon和64 GB RAM,nvcc 6.5.12。我將sm_20更改爲sm_35進行編譯。

PTX ISA中還有一個operands cost章節,雖然它不是很有幫助,但它只是重申了你的期望,卻沒有給出精確的數字。

+0

我也在使用特斯拉K20,並試圖運行您提到的同一個微基準。你是否能夠毫無問題地運行'global.cu'?我問,因爲我面臨非法內存訪問問題 - 我已經發布了這個問題[這裏](http://stackoverflow.com/questions/36416843/how-to-write-a-pointer-chasing-benchmark-using- 64位指針合CUDA)。我想知道你是否對內核代碼做了任何更改以使其適用於你? – Kajal 2016-04-05 18:56:12

+0

@ kv.333它是前一段時間。我記得有一些問題,並沒有全部的基準。我不記得哪些。 – 2016-04-11 07:17:59