OpenCL 中的并发内核

哈纳塞

我想知道如何同时并行执行两个或多个不同的内核?显然在使用 OpenCL 的同一 GPU 中。我的主要想法是使用两个不同的内核(内核 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; }

struct VectorStruct 的定义如下:

struct VectorStruct { int x; int y; };

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

pmdj

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

您还可以使用多个串行命令队列实现类似的功能

对于您的简单内核,最好使用 afloat2来表示您的向量并在单个内核中执行向量化 (SIMD) 加法。OpenCL 编译器应该接收向量操作并自动在并行硬件中分配操作。

对于稍微更复杂的操作,这不能很好地工作,您可以将向量的 x 和 y 坐标表示为一个 2 元素数组,并简单地将两倍数量的工作项排入一个在交替维度上工作的内核上。

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

请注意,您的使用get_local_id(0)可能是错误的,这取决于您想要实现的目标——您可能希望get_global_id(0)在这种情况下使用。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章