2011-08-05 56 views
3

我目前正在實現一個算法,在小矩陣和向量上進行線性代數的分配。代碼很快,但我想知道是否有意義在gpgpu而不是cpu上實現它。撥打opencl需要多少時間?

我能夠將大部分的矩陣和向量作爲預處理步驟存儲在GPU內存中,並且具有乘法算法和算法的配置文件,這些算法在GPU上更快。

,但現在我真正的問題, 我怎麼判斷撥打電話從CPU GPU的開銷?我爲了執行代碼而損失了多少個週期?

我希望有人有一些輸入?

回答

6

很難確定調用OpenCL的確切「開銷」,因爲GPU上的操作可以與CPU上運行的任何其他操作並行完成。 根據您的應用程序,例如,您可以從應用程序將一大塊數據傳輸到GPU,然後在CPU中對以下數據塊進行預處理。同樣,當代碼在GPU上執行時,您可以在CPU上對將來需要的某些數據做一些準備工作。

傳輸到GPU將通過DMA傳輸完成,這些傳輸速度非常快。 根據我的經驗,我能夠將大約4MB數據傳輸到GPU(現代GPU,現代主板),同時對先前發送的數據進行一些處理。由此看來,可以安全地說,您可以每秒向GPU上傳和下載1GB數據的訂單,並對該數據進行一些處理。

在你的情況下,GPU或CPU端將成爲瓶頸。 CPU方面,如果它不能每秒向GPU提供1GB準備好的數據。這可能會受到磁盤I/O的限制。

要測試GPU路徑,請設置一堆準備處理的數據緩衝區。你會想重新發送這些數據到GPU,處理它,然後下載結果(你將丟棄它)。測量吞吐量並與應用程序CPU版本的吞吐量進行比較。

不要只測量GPU處理部分,因爲GPU上的傳輸和處理將爭奪GPU內存控制器時間,並且會影響彼此的速度。此外,如果您希望在小塊數據上獲得非常好的響應時間,但吞吐量不佳,您可能不會從GPU中受益,因爲它會給您的處理帶來一點延遲。

-1

我建議您使用以下測量CPU週期數:

#include <stdlib.h> 
#include <time.h> 

// ... 

clock_t start,end; 
start = clock(); 

// do stuff... 

end = clock(); 

cout<<"CPU cycles used: "<<end-start; 
+0

該解決方案的問題是clock()具有類似15-25ms的分辨率的事實。所以在小的時間尺度上它根本不準確:-( –

+2

也許叫你的功能10000次? – vsz

+0

這種溶劑將不起作用,因爲你要麼只是流10000次調用卡,並等待它們全部返回 - 包括返回或者等待個人回電,我並不是說要成爲一個有害生物,但必須有更好的方式 –

2

這裏要考慮的最重要的是它需要將數據複製到GPU和返回的時間。即使GPU的實現速度快得多,花費在傳輸上的時間也可能會消除任何優勢。此外,如果您對代數的準確性非常認真,那麼您可能需要考慮您希望執行的操作可能無法以雙精度在GPU上本地提供。

鑑於你說你的矩陣和向量很小,我建議檢查一下可能會提高CPU上算法性能的SIMD優化。

+0

我很幸運,我必須爲每個電話轉移的數據可以歸爲到一個整數,所以傳輸可以忽略,真正的問題是設置內核調用和執行調用時的時間延遲。 –

1

您可以使用clEvent對象來跟蹤實際計算所需的時間(延遲)。如果您實際上是指CPU週期,請使用RDTSC(或MSVC中的內部__rdtsc)爲實際的API調用執行納秒精度的時序。 RDTSC指令(讀時間戳記計數器)返回自上電以來CPU完成的時鐘週期數。

如果真的很容易上傳,那麼您可以批量調用,也許可以添加一個維度到您的NDRange在一次調用中執行多個計算。當然,細節取決於你的內核實現。