2013-05-30 67 views
1

我有一個10行96列的2D主機陣列。我將這個數組以線性方式加載到我的cuda設備全局內存中,即row1,row2,row3 ... row10。CUDA 5.0內存對齊和合並訪問

該數組的類型爲float。在我的內核中,每個線程都從設備全局內存訪問一個浮點值。

The BLOCK_SIZE I use is = 96 
The GRID_DIM I use is = 10 

現在我從「CUDA C語言編程指南」爲凝聚的訪問理解,我使用的模式是正確的,由經連續訪問存儲位置。但是有一條關於內存128字節內存對齊的條款。我無法理解。

Q1)128字節內存對齊;這是否意味着warp中的每個線程都應該從地址0x00(例如)開始訪問4個字節,直到0x80? Q2)因此,在這種情況下,我是否會進行不合並的訪問或不合並?

我的理解是:一個線程應該使一個內存訪問應該是4個字節,地址範圍從0x00到0x80。如果來自變形的線程訪問其外部的位置,則它是未合併的訪問。

回答

8

全局內存中的負載通常以128字節的塊爲單位完成,在128字節的邊界上對齊。合併內存訪問意味着您將所有來自您的warp的訪問保留爲一個128字節的塊。 (在較老的卡片中,內存必須按線程ID順序訪問,但較新的卡片不再具有此要求。)

如果您的warp中的32個線程每讀取一個浮點數,您將讀取總數爲128來自全局內存的字節。如果內存正確對齊,所有讀取將來自同一個塊。如果對齊關閉,則需要兩次讀取。如果您執行類似a[32*i]的操作,則每次訪問都將來自全局內存中不同的128字節塊,這將非常緩慢。

只要warp中的所有線程都訪問同一個塊,那麼訪問哪個塊並不重要。

如果你有一個96個浮點數組,那麼如果你的warp中的索引爲i的每個線程訪問a[i],它將是一個合併讀取。與a[i+32]a[i+64]一樣。

因此,Q1的答案是所有線程都需要保持在128字節邊界上對齊的128個字節的同一塊中。

回答你的第二季度是,如果你的陣列排列正確,你的訪問是形式a[32*x+i]i線程ID和x任意整數,它是所有線程一樣的,你的訪問將被合併。

根據編程指南的第5.3.2.1.1節,內存始終與至少256個字節邊界對齊,因此使用cudaMalloc創建的陣列總是正確對齊。

+0

謝謝@Jeffrey。它澄清了我所有的疑問。 – fahad