2016-11-18 51 views
2

我在這裏看到了堆棧溢出處理相同問題的幾個問題,但沒有明確的答案。我想我會再問一次,並附帶一些我自己的問題。都涉及到手頭的主題。何時發生OpenCL數據傳輸?

那麼,我們知道從主機到openCL設備的數據傳輸何時發生嗎?你能告訴我下面的函數(即,哪些數據被傳輸或創建的,如果有的話,當這些函數被調用?)確切的內存傳輸操作:

clCreateBuffer()

clSetKernelArg()

clEnqueueNDRangeKernel()

前兩個甚至不會產生事件,所以我們無法計時,但肯定會發生一些數據傳輸。

有沒有辦法將數據傳輸到設備,而無需先將其設置爲內核arg?

從我自己的初步測試中可以看出,使用CL_MEM_USE_HOST_PTR創建的mem對象直接被設備操作。爲什麼這樣做不可取,因爲這樣我們就可以避免進一步的數據傳輸命令(並且驅動程序肯定會以最有效的方式實現)?

在內核返回後,傳輸的數據(比如,作爲內核arg的參數)是否留在設備上以供進一步操作?如果沒有,有辦法做到這一點?

回答

2

緩衝區副本與命令隊列有關。命令隊列與主機同步使用finish()作爲最簡單的方法。

clCreateBuffer() 

    clEnqueueWriteBuffer() <-------- you can get event data from this 
     (set blocking parameter to false to queue everything quickly) 
     (set blockinig to true if you sync write here) 

clSetKernelArg() 

    clEnqueueWriteBuffer() <----- it could be here too 

clEnqueueNDRangeKernel() 

    clEnqueueWriteBuffer() <----- or here (too quickly re-set an array?) 

clFinish() <--------- this ensures all queued commands are executed before this 

now you can query data of that event to check when it started and when ended 

讓一個緩衝留在設備,你應該在設備創建它首先那就不要將其遷移到另一臺設備。在createBuffer()中只使用CL_MEM_READ_WRITE標誌足以使其成爲設備端的真正緩衝區,直到您釋放該緩衝區。

CL_MEM_USE_HOST_PTR或CL_MEM_ALLOC_HOST_PTR使用主機內存作爲設備將其映射到其核心。由於主機端不需要額外的數據移動,因此數據流入和流出速度更快。如果您需要始終使用設備內存(如fast gddr5或hbm),則不應使用這些標誌。

複製到設備一次,儘可能多地使用。如果設備有自己的記憶,當然。例如,Intel HD Graphics 400沒有自己的內存並共享RAM,所以使用CL_MEM _... HOST_PTR標誌尤其是USE_HOST_PTR要快得多。

要檢查設備是否與CPU共享RAM,請查詢設備的CL_DEVICE_HOST_UNIFIED_MEMORY屬性。

看來(從我自己的初步測試),其與CL_MEM_USE_HOST_PTR創建的MEM對象 被直接由 設備

操縱即使沒有地圖/取消映射命令PROR到內核執行我的計算機行爲相同,但我使用map/unmap只是爲了安全,並且不會浪費太多週期。

編輯:如果你想確保一個命令在你想要的時候沒有啓動,你可以在bufferwrite命令的事件列表輸入參數中添加一個用戶事件。然後,您可以觸發用戶事件以讓寫入開始,因爲命令在繼續之前等待列表中的所有事件被觸發+完成(如果在事件列表輸入參數中有任何指定),則等待