[英]Sum reduction with parallel algorithm - Bad performances compared to CPU version
我已經實現了一個小代碼,可以減少一維數組的總和。 我正在比較CPU順序版本和OpenCL版本。
該代碼可以在這個鏈接1
內核代碼在此鏈接上可用2
如果要編譯: Makefile的link3
我的問題是關於GPU版本的不良表現:
對於小於1,024 * 10 ^ 9個元素的向量(即1024, 10240, 102400, 1024000, 10240000, 102400000 elements
),GPU版本的運行時高於(略高但更高)CPU版本。
如您所見,我采用了2 ^ n個值,以使工作項的數量與工作組的大小兼容。
關於工作組的數量,我采取了以下措施:
// Number of work-groups
int nWorkGroups = size/local_item_size;
但是對於大量的工作項,我想知道nWorkGroups的值是否合適(例如, nWorkGroups = 1.024 * 10^8 / 1024 = 10^5 workgroups
,這不是太多嗎?)。
我試圖在[64, 128, 256, 512, 1024]
loca_item_size
范圍內修改loca_item_size
,但是對於所有這些值,性能仍然很差。
我僅對size = 1.024 * 10^9
元素有好處,這是運行時:
Size of the vector
1024000000
Problem size = 1024000000
GPU Parallel Reduction : Wall Clock = 20 second 977511 micro
Final Sum Sequential = 5.2428800006710899200e+17
Sequential Reduction : Wall Clock = 337 second 459777 micro
從您的經驗來看,我為什么會表現不佳? 盡管與CPU版本相比,我的優勢更顯着。
也許有人會在源代碼中看到一個主要錯誤,因為目前我無法解決此問題。
謝謝
好吧,我可以告訴你一些原因:
您無需編寫縮減緩沖區。 您可以使用clEnqueueFillBuffer()
或幫助程序內核直接將其清除在GPU內存中。
ret = clEnqueueWriteBuffer(command_queue, reductionBuffer, CL_TRUE, 0, local_item_size * sizeof(double), sumReduction, 0, NULL, NULL);
除了上次讀取的內容外,不要使用阻塞呼叫。 否則,您會在那里浪費時間。
您正在最后一次減少CPU。 通過內核進行迭代處理可以提供幫助。
因為如果您的內核每次減少128個元素。 您的10 ^ 9號碼降到8 * 10 ^ 6。 CPU負責其余的工作。 如果在其中添加數據副本,則將使其完全不值錢。 但是,如果以每遍512個元素運行3次遍,則僅從GPU讀取10 ^ 9/512 ^ 3 = 8個值。 因此,唯一的瓶頸將是第一個GPU復制和內核啟動。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.