OpenCL中的并发内核

时间:2018-11-16 15:58:11

标签: memory kernel opencl

我想知道如何并行执行两个或多个不同的内核?显然是在同一GPU中使用OpenCL。 我的主要思想是使用两个不同的内核(内核A和内核B),但是它们需要使用相同的内存(我不想通过在“ a”和“ b”指针中为每个指针使用一个缓冲区来复制内存) 。那么,还有另一种方法可以通过有效的内存技术来完成双重执行吗? 内核代码如下: 内核A:

_kernel  void kernelA(global struct VectorStruct* a, int aLen0, global struct VectorStruct* b, int bLen0, global struct VectorStruct* c, int cLen0) {
int i = get_local_id(0);
c[(i)].x = a[(i)].x + b[(i)].x; }

内核B:

_kernel  void kernelB(global struct VectorStruct* a, int aLen0, global struct VectorStruct* b, int bLen0, global struct VectorStruct* d, int cLen0){ int i = get_local_id(0); d[(i)].y = a[(i)].y + b[(i)].y; }

结构VectorStruct的定义如下:

struct VectorStruct { int x; int y; };

在主机代码中,我必须创建四个指针: VectorStruct * a VectorStruct * b VectorStruct * c VectorStruct * d 指针“ a”和“ b”具有我将传输到GPU的数据。指针“ c”将存储内核A的结果,指针“ d”将存储内核B的结果。

1 个答案:

答案 0 :(得分:0)

您可以在{em> concurrent 命令队列中将clEnqueueNDRangeKernel()放入2个内核,即在clCreateCommandQueue期间传递CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE的队列。然后将两个创建的事件对象传递给缓冲区读取或映射调用,以从主机读取结果。请注意,并非所有的硬件和OpenCL实现都支持同时执行不同内核,因此毕竟它们可能最终在某种程度上被序列化了。

您还可以通过多个 serial 命令队列实现类似的功能。

对于简单的内核,最好使用float2表示向量,并在单个内核中执行向量化(SIMD)加法。 OpenCL编译器应选择矢量操作并自动在并行硬件之间分配这些操作。

对于不太好用的复杂操作,您可以将向量的x和y坐标表示为2元素数组,并在一个交替工作的内核上简单地将两倍的工作项排队尺寸。

这两种方法都将为您提供更有效的内存访问模式。

请注意,根据您要实现的目标,您对get_local_id(0)的使用可能是错误的-在这种情况下,您可能希望使用get_global_id(0)