2012-11-06 42 views
3

我目前正在向OpenCL遷移一個相當不錯的匹配追蹤算法(這是較大圖像處理算法的一部分)。處理OpenCL內核中的臨時矩陣和私有內存

該算法使用一些內部矩陣和向量進行處理。其中一半大小相當小(少於10列),但另一半則可能因輸入矩陣(n * n,2n * n等)而變得相當大。

所有內部矩陣的定義取決於輸入矩陣。

鑑於標準中沒有本地分配功能,我通過將內存塊從全局內存映射到工作項的私有內存來解決內存問題。在上下文設置期間,我確保塊不重疊,以便在運行時確保數據一致性。

這種方法對我來說並不合適。這感覺更像是一個黑客。

你們有沒有遇到過這種情況?你的解決方案是什麼?

+0

好的。你可以在那裏遷移嗎?或者我應該在SO上重新發布? –

+0

我覺得主持人可以;我會標記它,以便引起他們的注意。 –

+0

Paul,你能否澄清你說你是從全局映射到私有內存塊的含義?你的意思是你在你的函數中聲明瞭一個數組,並且從作爲內核參數傳遞的全局指針中將數據複製到它中? –

回答

2

像這樣分割一個全局內存緩衝區很好,雖然通常只用於輸出回主機。全球內存訪問的成本通常數百個指令週期的,所以我建議你:

  1. 分配臨時數據__private或__local內存代替。對於後者,請檢查CL_DEVICE_LOCAL_MEM_SIZE,通常爲16KB-64KB。請記住,多處理器上的__本地內存是跨工作組共享的;如果使用過多,即使在CL_DEVICE_LOCAL_MEM_SIZE限制內,這也會對多處理器的佔用率以及吞吐量產生負面影響。觀察這一點的最佳方式是通過對工作負載+設備進行實驗。

  2. 如果您的臨時矩陣對於__本地內存來說太大,請考慮是否可以使每個工作項目更小,以便它適合並避免全局內存的相當大的開銷。

  3. 如果每個工作項目的最小數據足跡都有一些嚴格的限制,請按照您的描述使用__global內存。但是請確保您:

    • 啓動你用大量的工作組,這樣,而另一些則忙等待全球內存訪問,其他人可以在多處理機調度的內核(「延遲隱藏」)。
    • 只要供應商支持,就可以合併全局內存訪問。 NVidia OpenCL最佳實踐指南進行了一些詳細說明,並且> 100%的性能改進都是可以實現的。
+0

謝謝你的回答。 「請記住,多處理器上的__本地內存是跨工作組共享的」 - 我認爲__本地內存僅在工作項目而不是工作組中共享**。這是你的意思嗎? –

+0

抱歉可能更清楚。我的意思是說,雖然__local變量只能在工作組中訪問,但支持該變量的物理內存將在多個工作組之間共享。因此,如果您指定一個大小爲整個CL_DEVICE_LOCAL_MEM_SIZE的內核__local參數,則一次只能在多處理器上調度一個工作組。這通常會損害您的整體吞吐量。 –

+0

是的,現在很清楚。謝謝! –

1

你的方法似乎沒問題。你可以看看NVidias OpenCL best practice guide。在第3.2.2節 - 「共享內存」中 - 有一個矩陣乘法的例子。每個工作組將所需數據從全局內存複製到本地內存中。