2009年3月14日 星期六

CUDA - Vivian

[090314]

架構介紹

‧ 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 則留言:

Zhong-Ho Chen 提到...

加油~
看來我要趕快把SPIHT弄一弄了

SCREAMLab 提到...

照例我總是要問問問題.

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。

Zhong-Ho Chen 提到...

問題1:
blockid & threadid 是內建變數, 好讓thread知道自己的id, programmer可以利用這個id分配工作不同的thread

最常見的分法是把一大筆資料切成很多份, 每個thread負責處理一份資料, 這時後id就可以當成index來用

FFT的資料是1D的, 所以用1D的index就好了
矩陣處理就可以用2D的Index

Zhong-Ho Chen 提到...

問題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就可以解決了

Zhong-Ho Chen 提到...

問題3.
利用Shared-Memory或者External Memory溝通, 另外有__syncthreads()提供同步的機制

問題4.
C Library的Sin是用"Instruction"去查表, 到CUDA裡面就必需展開到Kernel Function裡面, 再加上可能有很多Control Path, 可能會蠻慘的

要去實驗才能知道會有多慘, 用硬體的話, 每個Thread都是用同一個Instruction, 應該會快不少

Zhong-Ho Chen 提到...

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

SCREAMLab 提到...

很棒, 這個串是部落格開張以來, 在最短時間內有最棒最多回應的串. 希望其他串可以在這點上跟它看齊.

感謝aaa and bbb.

所以我延續aaa回答的問題2.

假如塞不下, tool chain會如O.S.一樣幫你處理嗎?

另外每一個core有8192個registers, 那麼它可以multi-thread執行的話, thread與thread的切換由誰來決定呢? 為何不能執行超過8個threads假如每一隻吃掉1024個呢? 又何謂同時? 系統不是有external memory可以給你swap嗎?

Zhong-Ho Chen 提到...

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 大家都看的到

Zhong-Ho Chen 提到...

老師的問題2:
它提供的API應該就回傳個NULL告訴你沒有Memory了, 不太可能還幫你swap
就算有, 如果Addressing Space只有4G, 你要到8G該怎麼辦? 我也好希望有這麼神的Tool

Zhong-Ho Chen 提到...

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都不一樣

SCREAMLab 提到...

有一場在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