我想知道如何并行执行两个或多个不同的内核?显然是在同一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的结果。
答案 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)
。