在OpenCL 1.2内核之间传递变量/内核之间的通信
Passing variables between kernels in OpenCL 1.2 / Communication between kernels
我对OpenCL比较陌生。我使用的是OpenCL 1.2 c++包装器。假设我有以下问题:我有三个整数值a、b和c,它们都在主机
上声明int a = 1;
int b = 2;
int c = 3;
int help;
int d;
d是结果,help是帮助变量。
我想计算d = (a + b)*c。为了做到这一点,我现在有两个名为"加"answers"乘"的内核。
目前,我正在这样做以下方式(请不要被我的指针导向的编程方式混淆):首先,我创建我的缓冲区
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);
和乘法核
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);
这是一个很好的工作方式。但是,我不希望将help的值复制回主机,然后再返回到设备上。为了实现这一点,我想到了3种可能性:
- 在设备端提供帮助的全局变量。这样,两个内核都可以随时访问help的值。
- kernel增加在运行时调用内核乘法。然后,我们将c的值插入到添加内核中,并在添加完成后将帮助和c传递给乘法内核。
- 简单地将help的值传递给乘法内核。我在这里搜索的是OpenCL 2.0中可用的管道对象。有人知道类似的OpenCL 1.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的复制和内核"add"的执行可以并行化。
相关文章:
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 大小相等但成员数量不同的结构之间的性能差异
- OpenAcc标准中内核和并行指令之间的差异
- 使用用户模式和内核之间共享内存的慢速通信
- 如何在 CUDA 网格中所有线程之间共享的__global__内核中定义变量
- 如何在内核之间同步 TSC
- 如何在进程之间共享内核对象,例如可等待计时器
- 根据内核/掩码在相关的相邻像素之间有效地迭代
- 互斥锁如何确保变量的值在内核之间保持一致?
- 当结合BSP库和std::vector时,我无法在内核之间发送数据
- 在OpenCL 1.2内核之间传递变量/内核之间的通信
- 预测 2.6.16 和 2.6.26 内核版本之间的"kernel too old"错误
- 内核和驱动程序之间的区别是什么