CUDA之thread訪問總結

2021-07-29 18:25:29 字數 1550 閱讀 9829

問:對於結構體陣列 typedef struct  float3;  float3 d=data[id], id為執行緒索引號,則對於乙個

wrap,為其中的每個執行緒讀取4位元組需要幾次訪存呢?為其中的每乙個執行緒讀取12位元組需要幾次訪存呢?

答:如果只是為warp中的每個執行緒讀1個該結構體的例項的乙個分量(4b)的話。那麼如果所有執行緒在都訪問的不是同乙個例項的情況下,最好的情況下,將只為每個執行緒讀取4b. 每個執行緒只生成1條訪存指令。但是這是所謂的requested讀取的大小,實際上,l2和視訊記憶體控制器都會將讀取放大的。例如假設你現在的訪問模型是warp中的每個執行緒都讀取連續的乙個該例項的乙個分量,因為我們的視訊記憶體不是真的隨機的,它有最小的傳輸粒度大小。你這樣每12b只要4b的話,實際上將有約3倍的讀取放大的。乙個warp將至少需要12次l2傳輸的(384b)。你可以用profiler報告的global memory實際讀取速率,和請求的讀取速率,觀察到大約前者實際是後者的3倍的大小。

關於第二個問題,因為n卡的硬體目前不支援96-bit讀取,如果你這結構體就這樣寫的話,無任何對齊上的暗示。那麼每個執行緒的對1個例項的訪問,只能被拆分成3條4b讀取的。(n卡目前支援64-bit和128-bit讀取的,但木有96-bit。這樣再無對其性的暗示的話,將只能拆分成3 * 32-bit。而不能1x64-bit + 1x32-bit)。

感謝來訪。

ps: 請按照提示觀察profiler報告的只讀取乙個分量時候的讀取放大效果(或者說,降低等效訪存能力到到1/3的效果)。

ps: 有內建的float3的,無需手工重新定義

問:那麼如果所有執行緒在都訪問的不是同乙個例項的情況下,最好的情況下,將只為每個執行緒讀取4b. 每個執行緒只生成1條訪存指令。這句話沒理解

答:如果1個warp只訪問同乙個float3的同乙個分量的話,這實際上結果可以被廣播到所有執行緒中的。只進行一次l2傳輸的(不考慮dram)。但如果訪問的是同時不同的float3的

乙個分量,則如同上文所說,l2將多次完成對warp的傳輸請求。

問:這個12次l2中的12次是不是通過如下方式計算:乙個執行緒訪問12位元組,所以乙個wrap就需要訪問32*12=384位元組,而一次訪問的最小傳輸粒度是32位元組,故382除以32等

於12次l2是嗎?

卡略有區別),l1採用的是128b的cache line的,可能會導致l2傳輸更多。(如果你認為這樣對效能有利的話)。

問:那麼每個執行緒的對1個例項的訪問,只能被拆分成3條4b讀取的。這句話也就是說如果乙個執行緒要訪問結構體陣列中對應的乙個元素float3 d(12字

節 d.x  d.y   d.z),是需

要分三次訪問的,一次訪問d.x  一次d.y  一次d.z 共三次是吧?

答:嗯嗯。是的。這種情況下的 global memory讀取,編譯器將會生成三條4b讀取指令。

問:雖然第一次訪問d.x 時,l2的快取是32b,32b快取中可能已經包含有dy,dz;但是仍然需要第二次訪問d.y,第三次d.z是吧?

答:往往會直接從cache中傳過來。

指令是必須要有的。

但資料的**是另外一回事。

cuda合併訪問的要求 CUDA學習筆記(二)

1.高效公式 最大化計算強度 math memory 即 數學計算量 每個執行緒的記憶體 2.合併全域性記憶體 按順序讀取的方式最好 3.避免執行緒發散 執行緒發散 同乙個執行緒塊中的執行緒執行不同內容的 1 kernel中做條件判斷 2 迴圈長度不一 1 檢視本機引數 注 kernel的載入中,自...

CUDA中確定你顯示卡的thread和block數

在進行平行計算時,你的顯示卡所支援建立的thread數與block數是有限制的,因此,需要自己提前確定夠用,再進行計算,否則,你需要改進你的演算法,或者,更新你的硬體了.首先你需要知道你的顯示卡的compute capability 在目前市面上絕大多數的都是支援1024 threads 只有一些非...

CUDA總結1 OpenCV與CUDA簡介

因為演算法的需要,正常的cpu演算法速度不夠需要進行加速,opencv中正好加入了gpu計算的模組,opencv中有兩種gpu的加速方式,一種是通用標準的opencl,另一種是nvidia的cuda加速。opencl是蘋果公司提出的一種通用標準,多種平台支援的標準。cuda是nvidia提出的平行計...