我編寫了模擬簡單熱流的C++應用程序。它使用OpenCL進行計算。 OpenCL內核採用二維(n x n)溫度值及其大小(n)的陣列。它在每個循環之後返回與溫度新的數組:如何避免在OpenCL中持續存儲複製
僞代碼:
int t_id = get_global_id(0);
if(t_id < n * n)
{
m_new[t_id/n][t_id % n] = average of its and its neighbors (top, bottom, left, right) temperatures
}
正如可以看到,每一個線程被計算在矩陣的單細胞。當主機應用程序需要執行X計算週期看起來這
- 爲1 ... X
- 複製內存OpenCL設備
- 調用內核
- 複製存儲備份
我想重寫內核代碼來執行所有X週期沒有常量內存co去往/來自OpenCL設備。
- 複製內存OpenCL設備
- 調用內核X倍,或致電內核一次,並使其計算X週期。
- 複製存儲備份
我知道,當其他所有線程都在做他們的工作在內核的每個線程應該鎖定和後 - M [] []和m_new [] []應該被交換。我不知道如何實現這兩個功能中的任何一個。
或者也許有另一種方式來做到這一點最佳?
你能說出更多的事情嗎? 當內存實際上被複制到OpenCL設備? 1)創建緩衝區時:緩衝區A(上下文,CL_MEM_COPY_HOST_PTR,size,mem); 2)設置內核arg時:kernel-> setArg(0,A); 3)運行內核時:enqueueNDRangeKernel(...); 我已經在我的代碼中測量了一些時間,它對我仍然不清楚。 – Klepak
沒有一個。它在刷新隊列之後被複制,並且在它開始由gpu發出並且在enqueuewritebuffer命令完成之前被複制。假設所有命令都是非阻塞類型。如果enqueuewritebuffer被設置爲阻塞,那麼在退出該enqueuewritbuffer函數之前,緩衝區將完成複製。 clFinish()爲隊列創建一個啓動信號,這樣就開始了。 clFinish()是同步主機和設備以確保隊列是否完成的最簡單方法。但是,實現可能會讓命令立即開始,並且您可能需要將用戶事件處理程序置於頂部 –