2017-07-31 70 views
0

我想學習OpenCL,但我很難決定使用哪個地址空間,因爲我只找到彙編的資源來聲明這些地址空間是,但不是它們爲什麼存在或何時使用它們。資源至少太分散了,所以在這個問題中,我希望彙集所有這些信息:什麼是所有的地址空間,它們爲什麼存在,何時使用哪個地址空間以及關於內存和性能的優點和缺點。OpenCL何時使用全球,私人,本地,恆定的地址空間

據我瞭解(這可能是過於簡化的),該GPU擁有兩個物理類型的存儲器:全局內存,遠離實際的處理器,因此緩慢的,但相當大的,並提供給所有工人,本地內存,靠近實際的處理器,速度很快但很小,無法從其他工作人員那裏訪問。

直觀上,local限定符確保將變量放置在本地內存上,並且global限定符可確保將變量放置在全局內存上,但我不確定這是否會發生。這留下了privateconstant限定符。那些人的目的是什麼?

還有一些隱式限定符。例如,the specifications提到通用地址空間,我認爲它用於沒有限定符的參數。這到底做了什麼?那麼也有局部函數變量。這些地址空間是什麼?

下面是一個使用我的直覺的例子,但不知道什麼,我實際上做:

例: 說我通過long類型和長度10000數組的內核,我只會用閱讀,那麼我會宣佈它,因爲它必須提供給所有工人,它不會改變。爲什麼我不使用constant限定符?當通過CPU爲這個數組設置緩衝區時,我實際上也可以使數組只讀,這在我眼中說與聲明const相同。那麼,何時以及爲什麼我會聲明constantglobal const

執行內存密集型任務時,最好是將數組複製到內核中的本地數組中?我的猜測是本地內​​存太小,但如果數組只有10的長度呢?陣列何時會太大/太小?更一般的:什麼時候將數據從全局數據複製到本地內存?假設我也想傳遞這個數組的長度,然後我將const int length添加到我的內核的參數中,但我不確定爲什麼我會省略global限定符,除非因爲我看到其他人這樣做。畢竟,所有員工都必須接觸到length。如果我是對的,那麼length就會有一個通用的地址空間,但是我再也不知道這意味着什麼。

我希望有一些經驗的人可以清楚這一點。這不僅對我來說很棒,而且對希望獲得關於GPU上的內存管理的實用知識的其他愛好者也是如此。

+0

常量:從所有內核訪問同一個單元的速度很快。全局:訪問合併後的鄰居地址很快。本地:沒有碰撞的訪問很快。私人:它的速度很快。例外:單個全局/本地可以廣播到所有內核。全球服務gpu的全部核心,本地服務一個計算單元的全部核心,不斷服務於gpu的全部核心,私有服務單核心。按核心,我的意思是工作項目。 –

回答

3

常量:所有工作人員都可以看到一小部分緩存全局內存。如果可以,請使用它,只讀。

全球:慢,所有人都可以看到,讀或寫。這就是你的所有數據都會結束的地方,所以對它的訪問總是必要的。

本地:您是否需要在本地組中共享某些內容?使用本地!你所有的本地工作人員是否都訪問相同的全局內存使用本地! 本地記憶僅在本地員工內部可見,並且尺寸有限,但速度非常快。

私有:內存只對工作人員可見,認爲它像寄存器。所有未定義的值默認爲私有。


說我傳遞給內核型長,長度10000我 將只用來讀取數組,然後我將宣佈其全球常量,因爲它必須 提供給所有工人和其不會改變。爲什麼我不會使用 常量限定符?

其實,是的,你可以和你應該使用constant限定符。將數據放置在常量內存中(所有工作人員可以快速訪問的只讀內存的一小部分)。這由GPU使用來將制服轉移到所有頂點着色器。

當通過CPU設置該陣列的緩衝,其實我也只是 可能做了數組只讀的,這在我的眼睛說, 與聲明爲const。那麼,何時以及爲什麼我會聲明 某些常量或全局常量?

不是真的,當你創建只讀你只specifiying到OpenCL的你打算使用它只讀的,所以它可以在後面做優化,但實際上你可以從內核寫入它的緩衝區。 global const只是開發者的一個保障,所以你不會意外寫入它,它會在編譯時發生錯誤。基本上,和普通的C主機端計算一樣。如果所有內存都是非常量的,程序也可以正常工作。

執行內存密集型任務時,最好是將數組複製到內核中的本地數組中?我的猜測是本地內​​存太小,但如果數組只有10的長度呢?陣列何時會太大/太小?更一般的:什麼時候將數據從全局數據複製到本地內存?

只有所有工作人員都閱讀纔有價值。如果每個工作人員讀取全局內存的單個值,那麼這是不值得的。 這裏很有用:

Worker0 -> Reads 0,1,2,3 
Worker1 -> Reads 0,1,2,3 
Worker2 -> Reads 0,1,2,3 
Worker3 -> Reads 0,1,2,3 

沒有用在這裏:

Worker0 -> Reads 0 
Worker1 -> Reads 1 
Worker2 -> Reads 2 
Worker3 -> Reads 3 

說我也想通過這個數組的長度,然後我想補充 const int的長度,以我的內核的參數,但我不確定爲什麼我 會省略全侷限定符,除非我看到其他人 這樣做。畢竟,所有工作人員都必須接觸到長度。如果 我是對的,那麼長度將有一個通用的地址空間,但再次,我不知道這意味着什麼。

當你不指定內核參數,它通常違約率預選賽constant,這是你想要的那些小的單元,有由全體職工快速訪問。

OpenCL編譯器關於內核參數遵循的規則是:如果只讀取並且適合常量,常量或其他全局參數。

+0

謝謝,這澄清了一些事情。只是一些問題:如果我理解正確,通用地址空間中的所有變量實際上只是由編譯器分配給另一個地址空間。那麼局部函數變量呢? – Safron

+0

函數在OpenCL中並不是真正的函數。它們始終由編譯器內聯,因此它們將傳遞給它們的變量所使用的地址空間。在極少數情況下,您在需要地址空間的函數中使用方法(原子,屏障等)時,應在函數中定義它,以便編譯器在錯誤使用函數時給出錯誤。 – DarkZeros