架構介紹
‧ CUDA中,分為host和device兩部分。Host通常是指CPU。而 Device是host的coprocessor,它有自己的memory,可以跑平行的threads,在這裡我們指GPU,然而它也可以是其他的parallel processing device。在Device上跑的程式區段,我們稱為kernel。
‧ In CUDA program, serial 程序交給host (CPU)來做,而其中可以highly parallel的部分,我們寫成kernel function,放到device (GPU)上執行。
流程簡單敘述如下,host端將資料和kernel給GPU,GPU執行kernel,CPU在這同時可以做其他的事情或是等待GPU的資料return。
Serial code executes on the host while parallel code executes on the device.
‧ Thread Hierarchy
1. Thread : 執行的最小單位,每個thread都有一個獨特的threadIdx , a 3-component vector,so threadIdx can be 1D , 2D, or 3D, 方便我們去 domain 程式使用的vector 或 matrix的元素。
數個Threads組成一個block。
Note : GPU上的thread 較 CPU上的light weight,因為是用硬體去做,耗費的cycle較少。但是CPU到GPU之間存取等會耗掉不少時間,因此只有當程式能"highly" parallel,整體的效率才會有顯著的增進。
2. Block : 同一個block的threads可以使用共用的share memory來合作或同步,此外,__syncthreads()函數也可以使block中所有的threads都同步到了這個點時,才讓所有的threads繼續執行下去。目前的GPU一個block可以包含512 個threads。
數個Blocks再組成grid,同樣地,一個block 有獨一的blockIdx, which can be 1D or 2D.
‧ Memory Hierarchy
1. register & local memory : 每個thread有自己可以存取的 registers,在 kernel function 裡宣告的 automatic variable 會存在 register,但是當 automatic variable 數量多於一個thread可使用的register數量,或是 array型態的變數,以上這些會存在local memory。local memory 實際上是在 DRAM,速度較register慢許多,使用上要謹慎考慮效率問題。
2. Shared memory: 同一個block的threads可以存取的共同memory,效率快,它的Lifetime 與此所屬的block一樣長。
3. Global memory: 相當於GPU的DRAM,可以被host和device的每個thread存取,可以用於host和device交換資料使用,但是data access latency很長。
4. Constant and texture memory spaces : two additional read-only memory spaces accessible by all threads. The global, constant, and texture memory spaces are persistent across kernel launches by the same application.*All above figure from Nvidia Programming Guide.
*參考資源
Nvidia CUDA document
國網中心CUD教學課程
Hotball's Hive
-------------------------------------------------------------------------------
大家好,我是碩零的新生Vivian,也可以叫我小聽~
下次會介紹關於programming的部分。
13 則留言:
加油~
看來我要趕快把SPIHT弄一弄了
照例我總是要問問問題.
1. 所謂的threadidx是甚麼與怎麼用呢? 這個1D, 2D or 3D的threadidx是與data有關?還是與thread的運作有關呢?
2. 我很好奇一隻thread可以塞的程式有多大? 可以使用的記憶體有多大? 喔! 不要跟我說它physically有多大, 因為physical有多大跟實際可以用的經常不一樣, 尤其當程式的記憶體體用得不好時?
3. block裡的 threads怎麼合作?
4. 我知道GPU裡面有個計算sin的硬體, 直接寫個sin(x)就可以了嗎? 我好奇他的速度有多快.
想問一個問題,Memory Hierarchy中的第四點Constant和texture memory,這部份的memory是擺在哪裡?印象中GPU似乎只有instruction cache,要執行前去抓instruction,不知道有沒有Memory Hierarchy的block diagram。
問題1:
blockid & threadid 是內建變數, 好讓thread知道自己的id, programmer可以利用這個id分配工作不同的thread
最常見的分法是把一大筆資料切成很多份, 每個thread負責處理一份資料, 這時後id就可以當成index來用
FFT的資料是1D的, 所以用1D的index就好了
矩陣處理就可以用2D的Index
問題2:
CUDA程式的概念, 是一連串的Kernel Function, 每次只執行一個Kernel Funcnction, Kernel Function放在External Memory, 全部的Thread共享同一個Kernel Function, 要用的時後再抓到自己Cache來執行, 所以只要External Memory擺的下就沒什麼問題.
通常一個Kernel Function會負責簡單的工作如: FFT/DCT, 放太大的Kernel Function意義不大, 很有可能是程式沒切乾淨.
每個Kernel Function用到的Local Variable變數, 會放到GPU處理器的Registers, 每個處理器有8192的Register. 如果你的變數大小是1024, 代表這個處理器只能同時執行8個Thread, 如果變數大小超過8192, Tool Chain會把這些變數放到External Memory
所以結論就是Physical有多大就可以放多大
, Problem Size太大可能要User自己利用PC這邊的資源來處理, 目前還沒看到GPU有類似Virtual Memory的東西...
不過我認為知道這個意義可能不大, 一般的Kerneal Function可能都幾KB就可以解決了
問題3.
利用Shared-Memory或者External Memory溝通, 另外有__syncthreads()提供同步的機制
問題4.
C Library的Sin是用"Instruction"去查表, 到CUDA裡面就必需展開到Kernel Function裡面, 再加上可能有很多Control Path, 可能會蠻慘的
要去實驗才能知道會有多慘, 用硬體的話, 每個Thread都是用同一個Instruction, 應該會快不少
BBB的問題:
Memory Hierarchy for Instruction:
1. Instruction Cache
2. External Memory
Memory Hierarchy for Data:
1. Register(Local Variable)
2. Shared Memory (Shared Varaible)
Constant Cache
Texture Cache
3. Global Memory
Constant Memory
Texture Memory
國高的投影片沒有把Texture Memory說明的很清楚,我查了一下之後:
Texture/Constant 和 Global Memory一樣都放在External, Constant/Texture是Read Only, 讀Constant和Texture都有透過Cache, Constant和Texture的差別在於Texture Memory的Cache有是2D spatial locality
嗯嗯,所以global變數都是常數,Read only。
一個Processor Unit的單位是?一個Grid or 一個Block?
有圖看的話就太好了 :D
很棒, 這個串是部落格開張以來, 在最短時間內有最棒最多回應的串. 希望其他串可以在這點上跟它看齊.
感謝aaa and bbb.
所以我延續aaa回答的問題2.
假如塞不下, tool chain會如O.S.一樣幫你處理嗎?
另外每一個core有8192個registers, 那麼它可以multi-thread執行的話, thread與thread的切換由誰來決定呢? 為何不能執行超過8個threads假如每一隻吃掉1024個呢? 又何謂同時? 系統不是有external memory可以給你swap嗎?
CUDA的Memory Space:
1. Local Variable
2. Shared Memory
3. Global Memory
4. Constant Memory, Read Only
5. Texture Memory, Read Only
其中只有Local Variable是透過C的automatic variable來宣告, 其它幾個都是利用C的Pointer, 使用前要先利用API類似malloc來配置, 要指定配置的Memory Space
放到GPU之後:
1. Register
2. On-chip SRAM
3. DRAM, 直接存取
4. DRAM, Read Only Cache
5. DRAM, Read Only 2D Cache
* Register 只有 Thread 自己看的到
* On-chip SRAM 只有在同一個Block內的Threads看的到
* DRAM 大家都看的到
老師的問題2:
它提供的API應該就回傳個NULL告訴你沒有Memory了, 不太可能還幫你swap
就算有, 如果Addressing Space只有4G, 你要到8G該怎麼辦? 我也好希望有這麼神的Tool
CUDA的thread放到GPU之後
是由Streamming Multiprocessor (SM)來幫你執行, 每個SM最多可以"真同時"執行768threads.... 如果超過768 threads, middleware會自動幫你分時執行
每個SM只有8192個Register, 要給"真同時"執行的Thread去分, 每個Thread用1024的話, 那"真同時"執行的Thread就只有8個, 其它middleware會幫你分時執行
ps1. GPU上面可能有多個SM
ps2. 上面數字每個GPU都不一樣
有一場在NCKU的CUDA有關的seminar. 有興趣的可以去報名. 3/27, 2pm to 5pm.
http://www.nvidia.com.tw/object/tesla_E-invite_tw.html
http://www.eecs.stut.edu.tw/nvidia/?type=add
張貼留言