四月
12
2012
1

CUDA Performance

最近開始在kernel function中打轉,打算解決效能瓶頸!

假設我們都知道CUDA有這些memory了
global memory
local memory
shared memory
register

這是我用存取速度來排序的,我們發現一個很尷尬的東西local memory,明明是local卻比shared memory慢?

這點有許多謬誤,這個速度取決於你佔用local memory的大小,CUDA原則上會儘量把local memory分配到register中,但若存不下才分配到global memory中,但這不代表local memory永遠比shared memory慢,因為你知道它有機會存在最快register中。

這關係到一個大問題,許多人都認為(甚至連CUDA的教科書)以大量的thread來hide memory latency可以獲得最高的效能,但這僅在你的thread occupied rate在80%以上才有明顯效果,但並非所有的問題都有辦法展開到全部的thread執行,另外一個極端是當你全部thread都用上了還想增加效能時,這時候我們可以考慮讓一個thread多做點事,利用register/local memory來hide memory latency,這可以在低thread occupied rate仍保有最高的效能輸出。

不要害怕分配小單位的local memory,因為它有很大機會是存在register

這到底有什麼好處? 一般我們為了避免直接存取global memory,都儘量使用shared memory,但本質上shared memory僅是cached global memory,還是需要經過bus存取global memory,那為什麼不要直接放在register中呢? 讓bus暢通使更多block來存取。

一個大原則使用記憶體,注意使用量必須是遞增,不是用大量的local memory
register > local memory > shared memory > global memory

Written by in: 電腦三兩事 | 標籤:
四月
11
2012
2

CUDA multiple/dynamic texture reference

最近論文慢到不用CUDA無法跑完的境界,在使用Texture Reference上遇到了許多問題,故寫下此整理後查

我遇到的問題是必須要做驚人次數的bi-linear interpolation warping,故希望能用GPU的texture mapping功能,但同時必須要在多張影像中間切換

先轉述一篇文章片段

Those of you who have used CUDA textures should be familiar with the insane programming interface that they present. Texture references can be declared only as global variables, and only in the file where you are using them. You can't pass them around as by-value/by-reference arguments in functions, you can't create them inside function/class scope, and you cannot make arrays of them.

我們都看到這些限制拉,既然不能做texture reference array,這也代表我們不能在kernel function中index它,故每張影像一個texture reference是不可行的,當然這並不包括你硬刻影像數量的texture reference array在code中,同時你還必須受到一個kernel function僅能access 128個texture rerference的限制,並且在未知影像數量下也做不到硬刻code。

解決辦法一:在要使用texture時bind texture reference,但這似乎牽涉到複製到texture memory的問題,當你頻繁的切換時會有巨大的overhead。

解決辦法二:爛招合併所有影像到同一個texture,自然就可以僅用一texture reference,但你會受到texture size limit,這僅對小影像的合併有用,並且CUDA似乎不希望你開一個巨大的texture block,會在runtime時死掉,這個大小是與你的GPU記憶體無關的。還有另一個問題是你在fetch影像邊界的texture時可能會染到上下一張影像的pixel顏色,因為它當作是同一張圖了!

解決辦法三:使用3D texture reference,使用第三個維度來作為2D texture的影像index,但明顯的你的影像大小最好要全部一樣,並且也會發生解法二的顏色問題

解決辦法四:放棄使用你的高階CUDA語法,有low-level的解法,使用"DEPRECATED"的CUDA Driver API,咦?

解決辦法五:放棄使用CUDA! DirectX10有提供texture array! XDD

最終解法:使用cudaArrayLayered! interpolation 僅在該layer,不會跨layer interpolation

Written by in: 電腦三兩事 | 標籤:

Powered by WordPress | Theme: Aeros 2.0 by TheBuckmaker.com