2011-04-04 34 views
0

我寫一個CUDA內核矩陣的每一個元素上執行一個操作(例如squarerooting每一個元素,或冪,或者計算正弦/餘弦 - 在矩陣上的單個元素的操作如果所有的數字之間[-1; 1],等等。)CUDA - 讓思想

我選擇了塊/線程網格的尺寸,我覺得代碼非常簡單明瞭,但是我問自己什麼...我能做到最大化聚結/ SM佔用率嗎?

我的第一個想法是:從全局內存中加載所有半扭曲(16線程)加載數據集,然後將它們全部加以計算,但它發現沒有足夠的內存傳輸/計算並行化。線程加載數據,然後計算,然後再次加載數據,然後重新計算..這聽起來在性能方面真的很差。

我以爲使用共享內存會很好,也許使用某種地方來使線程加載更多的數據比實際需要其他線程的工作,但這聽起來也很愚蠢,因爲第二個會等待前者在開始工作之前完成數據加載。

我真的不知道我把關於我的問題,我只是開始對一些具體工作之前獲得思想的正確理念。

每個評論/建議/評論家都很受歡迎,謝謝。

回答

1

如果您已經定義了網格,以便線程沿包含你的矩陣陣列的主要尺寸讀取,那麼你已經保證合併的存儲器訪問,有沒有別的工作要做,以提高性能。這些類型的O(N)複雜度操作實際上不包含足夠的算術強度,以便在優化的CPU實現上實現良好的並行加速。通常最好的策略是將多個O(N)操作融合到一個單獨的內核中,以提高FLOP到內存的事務比率。

1

在我眼裏你的問題是這樣的

load data ensemble from global memory 

看來,你的算法思想是:

  1. 請在CPU的東西 - 有一些矩陣從全球到設備內存
  2. 傳輸矩陣
  3. 每個元素從設備
  4. 傳輸矩陣回到上執行您的操作全球內存
  5. 做別的事情上的CPU - 有時走回到1

這種計算的是幾乎每次I/O帶寬限制(IO =內存IO),而不是計算能力有限。 GPGPU計算可以承受非常高的內存帶寬 - 但只能從設備內存到GPU - 從全局內存傳輸總是會超過非常慢的PCIe(與設備內存連接相比速度較慢,最高可提供160 GB/s +快卡)。因此,獲得良好結果的一個主要方面是將數據(矩陣)保存在設備內存中 - 如果可能的話,最好在那裏生成它(取決於您的問題)。切勿嘗試在cpu和gpu之間遷移數據,因爲傳輸開銷消耗了所有的加速。還要記住,你的矩陣必須有一定的大小來平攤傳輸開銷,你不能避免(計算一個10×10的矩陣幾乎不會帶來什麼,甚至會花費更多)

交換傳輸/計算/傳輸完全正常,這就是這樣的GPU算法的工作原理 - 但只有當傳輸來自設備內存。

+0

不幸的是,我不知道何時這些矩陣(可能從10x10到​​20.000x20.000不等)將顯示出來計算。我需要編寫的CUDA模塊沒有鏈接到「矩陣生成」代碼(我甚至不知道) – 2011-04-04 14:04:30

+2

在這種情況下,您最好的選擇可能是在代碼中引入一些可調整的大小指標,以便當GPU的計算速度過小,因此您需要使用主機實現。你可以做一些基準測試,並開發一個簡單的執行時間模型,它可以預測哪個是更有效的解決方案。還有一部分工作可以在GPU上完成,部分工作在並行的主機CPU上。我已經非常成功地使用了這個操作,例如gemm等O(N^3)操作。 – talonmies 2011-04-04 14:23:31

+0

@Paul:然後期望在小矩陣上加速並在大矩陣上加速。你是否必須在相同的矩陣上或先前矩陣的結果上按順序計算元素運算?不惜一切代價避免轉移。只是給你一些數字:如果每個元素的計算都不是很大(只是sqrt很小),那麼極限是IO,對於現代DDR3計算機來說,20 GB/s是沒有問題的,即32如果你不在GPU上做更多的計算(在同一個矩陣上進行多次操作),你就不需要任何存儲,但是它會花費你的時間! – flolo 2011-04-04 14:24:54

0

對於這種微不足道的東西,GPU是過度殺傷性的,並且比將其保留在CPU上要慢。特別是如果你有一個多核CPU。

我已經看到很多項目顯示GPU在GPU上的「巨大」優勢。他們很少經受審查。當然,想要打動經理人的愚蠢經理人想要展示他的團隊是如何「領先」的。

有人在該部門的勞碌上得到愚蠢的GPU代碼優化個月(這是一般8X難度比相當於CPU的代碼讀取),然後有一些印度血汗工廠(其最後一個項目的程序員編寫的「等效」 CPU代碼是PGP),用最慢版本的gcc進行編譯,沒有進行優化,然後宣傳他們的2x速度改進。順便說一句,許多人忽視I/O速度,因爲某種程度上並不重要。

+0

我發現自己同意你的意見,但使用CUDA來計算單個元素的想法不是我的,而是我的老闆'。無論如何,我需要微笑,否則我會被解僱和86'd .. – 2011-04-04 15:04:44