2012-10-01 207 views
2

在試圖改善一些OpenCL的計算性能,我用一個clEnqueueWriteBuffer呼叫OpenCL運行的分析功能,以及緊隨其後的clEnqueueNDRangeKernel(取決於以前的數據轉院):clEnqueueWriteBuffer究竟做了什麼?

clEnqueueWriteBuffer(cmdq, cl_buf, CL_FALSE, 0, size, data, 0, NULL, &write_ev); 
clEnqueueNDRangeKernel(cmdq, ker_with_cl_buf_as_input_param, 2, NULL, 
    work_sze, local_sze, 1, &write_ev, &ker_ev); 

這裏是由clGetEventProfilingInfo返回(我中減去初始時間並轉換爲微秒):

  QUEUED SUBMIT START  END END-START 
write_ev  0 113.952 120.448 211.136  90.688 
ker_ev 130.016 132.608 217.280 515.200  297.920 

我的問題是:

  1. 爲什麼clEnqueueWriteBuffer在內存傳輸啓動或提交之前沒有返回?
  2. 更重要的是,爲什麼轉移實際需要很長時間?

在我看來,只要內存傳輸可以立即開始,就可以獲得22%的性能。 在實際進行傳輸之前,clEnqueueWriteBuffer是否會複製另一個主機內存區域中的數據?

其他信息:

我使用特斯拉M2090 GPU CUDA的4.1框架。

緩衝創建以前使用:

cl_buf = clCreateBuffer(my_context, CL_MEM_READ_ONLY, size, NULL, NULL); 

編輯:clEnqueueReadBuffer不表現出這種行爲。

回答

3

您可以嘗試使用固定內存,如NVidia OpenCL Best Practices Guide的第3.1.1節中所述。

他們沒有提到在使用可分頁內存時是否執行了複製,但可能會發生。

+0

是的,我認爲你是對的,當使用固定內存時,這個大的延遲消失。所以驅動程序可能會複製數據,或者做一些其他的事情來從常規內存中傳輸,這需要一些時間...... –

2

在開始異步複製之前,寫入操作應進行一些檢查。該檢查包括參數中的有效緩衝區類型,緩衝區不對齊,緩衝區的分配以及寫入等。

在clEnqueueWriteBuffer函數中,只有數據的原始副本是異步的,但準備不是。

+0

而閱讀不? –

+0

@natchouf這個讀操作沒有相同的檢查,也沒有保留緩衝區來編寫 – Zhen

+0

,這對緩衝區的第一次使用(其中寫入實際需要更長時間)肯定是正確的,但是我對後續的重用有懷疑。 .. –