最近開始在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