【问题标题】:OpenCL: same kernel in separate queuesOpenCL:不同队列中的相同内核
【发布时间】:2020-01-17 04:00:48
【问题描述】:

OpenCL 1.2:我在两个单独的命令队列中运行一系列内核,以便可以同时调度它们,最后同步。这些中使用了单独的数据缓冲区 排队。

我首先在不同的队列中使用相同的内核对象。然而,这似乎得到 两个队列之间的数据缓冲区都混在一起了。我抬头看了看,但在里面找不到任何东西 这方面的参考资料。特别是,我看不到 clSetKernelArgs() 中明确提到的任何内容 关于此的页面。有一张纸条说

用户不得依赖内核对象来保留指定为内核参数值的对象。

我不确定这是否适用于这种情况。

所以我设计的解决方案是内联内核代码并创建两个独立的内核函数 为两个并行队列中的每个内核调用此代码。这解决了问题。

但是: (1) 我对此不满意,因此我在不同的设备上再次进行了测试。数据缓冲区是 在 Intel HD630 GPU 中混乱,但在 AMD Radeon Pro 560 中没有(一切都很好)。 (2) 此解决方案无法扩展。如果我想实现更大量的任务并行 使用相同的上下文,为每个并行流做单独的内核是不好的。我有 没有测试两个单独的上下文,我认为它会起作用,但它意味着复制 在同步点从一个上下文到另一个上下文的数据,这破坏了整个练习。

有没有人尝试过这个,或者对这个问题有任何见解?

【问题讨论】:

    标签: opencl


    【解决方案1】:

    所以我设计的解决方案是内联内核代码并制作两个单独的内核函数,为两个并行队列中的每个内核调用此代码

    您不需要这样做。您可以通过简单地从同一个cl_program 创建多个cl_kernel 对象来实现相同的效果。只需使用相同的参数多次调用clCreateKernel。如果有帮助,您可以将 cl_kernel 视为一个结构,其中包含 1) 指向某些可执行代码的指针,以及 2) 存储参数。 cl_kernel 实际上并不“拥有”代码;程序会。

    但是,这似乎使两个队列之间的数据缓冲区都混在一起了

    您是否知道队列的命令执行顺序没有隐式保证?

    示例:如果您有一个有序的cl_command_queue,则将命令 A 和 B 加入其中可以保证 A 将在 B 之前执行。但是,如果您有两个命令队列 C1 和 C2,如果您将 A 排入 C1,然后将 B 排入 C2,则 B 可以在 A 之前执行(或 A 在 B 之前)。

    如果您需要强制执行特定顺序,则必须使用事件。像这样:

    cl_event ev;
    cl_kernel A, B;
    cl_command_queue C1, C2;
    ...
    clEnqueueNDR(C1, A, ... , &ev);
    clEnqueueNDR(C2, B, ..., 1, &ev, NULL);
    clReleaseEvent(ev);
    

    这保证了 B 在 A 之后执行。

    【讨论】:

    • 不需要强制执行顺序,只在同步点,没关系,因为我已经在那里同步了。我应该提到我从相同的代码中尝试了两个内核,但是在某个地方出现了段错误(我认为是在 setArg 调用中)。但是,我没有坚持,所以我应该回去再试一次。
    猜你喜欢
    • 2019-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 2016-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多