一、概述
乙個執行緒網格是由若干執行緒塊組成的,每個執行緒塊是二維、三維的,擁有x軸、y軸、z軸。此時,每次最多能開啟y*x*z*t 個執行緒。
通常執行緒塊中線程數量最好是乙個執行緒束大小的整數倍,即32 的整數倍。由於裝置是整個執行緒束為單位進行排程,如果我們不把執行緒塊上的執行緒數目設成32的整數倍,則最後乙個執行緒束中有一部分執行緒是沒有用的,因此我們必須設定乙個限制條件進行限制,防止處理的元素超出x軸方向上所規定的範圍。
在程式中,要盡量避免使用小的執行緒塊,因為這樣做無法充分利用硬體。比如,一張解析度為1920*1080,我們可以分配 dim3 block_num(1080, 10) ; dim3 thread_num(192, 1);
在當前費公尺架構的硬體上,乙個sm可以處理8個執行緒塊,所以上述程式從應用層的角度來說一共需要1350個(總共10800個執行緒塊 / 每個sm 能排程的8個執行緒塊)sm來完成實現並行。
二、執行緒與執行緒塊
cuda 中線程與執行緒塊到底有什麼聯絡?cuda 的設計是用來將資料分解到並行的執行緒與執行緒塊中。它允許我們定義一維、二維、三維的索引(y*x*t)來方便我們在程式中引用一些並行結構。這樣就使得我們程式的結構和記憶體資料的分布建立一一對映,處理的資料能被分配到到單獨的sm 中。不論是在gpu上還是在cpu上,讓資料與處理器儲存緊密聯絡能使效能得到很大的提公升。
不過,在對陣列進行布局的時候,有一點需要我們特別注意,那就是陣列的寬度值最好是執行緒束大小的整數倍。如果不是,填補陣列,使它能充滿最後乙個執行緒束。但是這樣做會增加資料集的大小。此外,我們還需要注意對填充單元處理,它和陣列中其他單元的處理不同的。
三、x 與y 方向的執行緒索引
在乙個執行緒塊上分布乙個二維陣列也意味著需要兩個執行緒索引,這樣我們才可以用到二維的方式訪問陣列:
注意blockdim.x 與 blockdim.y 的使用,這個結構體是由cuda 執行時庫提供的,分布表示x軸和y軸這兩個維度上線程塊的數目。
例如,計算乙個32*16 維的陣列,假設排程四個執行緒塊,我們可以有下面的分布方式:
在實際中長方形的布局比正方向的布局優越,這是為什麼呢?主要有兩個原因:第一,同乙個執行緒塊中的執行緒可以通過共享記憶體進行通訊,這是執行緒協作中一種比較快的方式。第二,在同乙個執行緒束的執行緒儲存訪問合併在一起了,而在當前費公尺架構的裝置中,快取記憶體儲存器的大小是128個位元組,一次直接訪問連續的128個位元組比兩個分布訪問64個位元組要高效得多。在正方形的布局中,0-15號執行緒對映在乙個執行緒塊中,它們訪問一塊記憶體資料,但與這塊記憶體相連的資料區則是由另乙個執行緒塊訪問的,因此,這兩塊連續的記憶體資料通過兩次儲存訪問才獲得,而在長方形的布局中,這只需要一次儲存訪問的操作。
這兩種布局方式,執行緒塊和網格配置如下:
執行緒網格、執行緒塊及執行緒的維度如下:
其中:griddim.x ----執行緒網格x維度上線程塊的數量
griddim.y ----執行緒網格y維度上線程塊的數量
blockdim.x ---乙個執行緒塊x維度上的執行緒數量
blockdim.y ---乙個執行緒塊y維度上的執行緒數量
threadidx.x ---乙個執行緒塊x維度上線程索引
threadidx.x ---乙個執行緒塊y維度上線程索引
通過找出當前的行索引,然後乘以每一行的執行緒總數,最後加上在x軸方向上的偏移,我們便可以計算出相對於整個執行緒網格的絕對執行緒索引。具體點如下:
thread_idx = ((griddim.x * blockdim.x) * idy) + idx;
其中:
idx = (blockidx.x * blockdim.x) + threadidx.x;
idy = (blockidx.y * blockdim.y) + threadidx.y;
執行緒 六 執行緒池
1.可重用的固定集合執行緒池,以共享的無界佇列的方式來執行這些執行緒 executerservice threadpool executors.newfixedthreadpool 3 容納固定的執行緒 這個執行緒就是建立乙個固定大小的執行緒池,等待任務來的時候就取執行緒池中的執行緒進行任務的執行,...
併發程式設計學習筆記(六 執行緒組)
執行緒組其實就是執行緒的乙個集合,其中可以包含執行緒,也可以包含執行緒組,它和樹形結構非常相似。執行緒組可以有效的組織執行緒和執行緒組。父物件中有子物件,但不存在孫子物件。1 public class testthread implements runnable 9 catch interrupte...
Java多執行緒(六) 執行緒讓步
一 yield 介紹 yield 的作用是讓步。它能讓當前執行緒由 執行狀態 進入到 就緒狀態 從而讓其它具有相同優先順序的等待執行緒獲取執行權 但是,並不能保證在當前執行緒呼叫yield 之後,其它具有相同優先順序的執行緒就一定能獲得執行權 也有可能是當前執行緒又進入到 執行狀態 繼續執行!二 y...