2016-10-26 49 views
1

我對OpenCL比較陌生。我正在使用OpenCL 1.2 C++包裝器。說我有以下問題:我有三個整數值A,B和C都宣稱主機在OpenCL 1.2內核之間傳遞變量/內核之間的通信

int a = 1; 
int b = 2; 
int c = 3; 
int help; 
int d; 

d是我的結果,並幫助是一個幫助變量上。

我想計算d =(a + b)* c。要做到這一點,我現在有兩個名爲'add'和'multiply'的內核。

目前,我這個做下面的方式(請不要被編程的我指針化的方式混淆):首先,我創建我的緩衝區

bufferA = new cl::Buffer(*context, CL_MEM_READ_ONLY, buffer_length); 
cl::Buffer bufferB = new cl::Buffer(*context, CL_MEM_READ_ONLY, buffer_length); 
bufferC = new cl::Buffer(*context, CL_MEM_READ_ONLY, buffer_length); 
bufferHelp = new cl::Buffer(*context, CL_MEM_READ_WRITE, buffer_length); 
bufferD = new cl::Buffer(*context, CL_MEM_WRITE_ONLY, buffer_length); 

然後,我把我的核心論點加入內核

add->setArg(0, *bufferA); 
add->setArg(1, *bufferB); 
add->setArg(2, *bufferHelp); 

,爲multiplicatoin內核

multiply->setArg(0, *bufferC); 
multiply->setArg(1, *bufferHelp); 
multiply->setArg(2, *bufferD); 

於是我排隊我的數據加

queueAdd->enqueueWriteBuffer(*bufferA, CL_TRUE, 0, datasize, &a); 
queueAdd->enqueueWriteBuffer(*bufferB, CL_TRUE, 0, datasize, &b); 
queueAdd->enqueueNDRangeKernel(*add, cl::NullRange, global[0], local[0]); 
queueAdd->enqueueReadBuffer(*bufferHelp, CL_TRUE, 0, datasize, &help); 

和乘法

queueMult->enqueueWriteBuffer(*bufferC, CL_TRUE, 0, datasize, &c); 
queueMult->enqueueWriteBuffer(*bufferHelp, CL_TRUE, 0, datasize, &help); 
queueMult->enqueueNDRangeKernel(*multiply, cl::NullRange, global[0], local[0]); 
queueMult->enqueueReadBuffer(*bufferD, CL_TRUE, 0, datasize, &d); 

這工作的好方法。但是,我不想將幫助的值複製回主機,然後再次返回到設備上。爲了實現這一點,我想到了3種可能性:

  1. 幫助設備端的全局變量。這樣做,兩個內核都可以隨時訪問幫助的價值。
  2. 內核在運行時添加調用內核的乘法。然後,我們會將c的值插入到添加內核中,並在添加完成後立即將help和c傳遞給乘法內核。
  3. 只需將幫助的值傳遞給乘法內核即可。我在這裏搜索的東西就像管道對象,可用於OpenCL 2.0。有人知道OpenCL 1.2的相似之處嗎?

如果有人能夠提出最平滑的方式來解決我的問題,我將非常感激!

在此先感謝!

回答

2

沒有必要讀寫bufferHelp。只需將其保留在設備內存中。您建議的解決方案的編號爲1)的是cl::Buffers已經是設備內存中的全局變量。

這相當於你的代碼,並會產生相同的結果:

queueAdd->enqueueWriteBuffer(*bufferA, CL_FALSE, 0, datasize, &a); 
queueAdd->enqueueWriteBuffer(*bufferB, CL_FALSE, 0, datasize, &b); 
queueAdd->enqueueNDRangeKernel(*add, cl::NullRange, global[0], local[0]); 
//queueAdd->enqueueReadBuffer(*bufferHelp, CL_FALSE, 0, datasize, &help); 

queueMult->enqueueWriteBuffer(*bufferC, CL_FALSE, 0, datasize, &c); 
//queueMult->enqueueWriteBuffer(*bufferHelp, CL_FALSE, 0, datasize, &help); 
queueMult->enqueueNDRangeKernel(*multiply, cl::NullRange, global[0], local[0]); 
queueMult->enqueueReadBuffer(*bufferD, CL_TRUE, 0, datasize, &d); 

注:我也改變了阻塞寫調用,這將提供更好的速度,因爲緩衝液C和內核的執行副本「添加」可以並行化。

+0

哇,我不能相信它的作品很簡單,非常感謝! 僅供其他讀者使用:我添加了queueAdd-> finish();在上述答案的第一個塊的末尾確保第一個內核已經完成。 – YeahScience