【问题标题】:Asynchronous execution of commands from two command queues in OpenCL在 OpenCL 中异步执行来自两个命令队列的命令
【发布时间】:2012-10-06 08:49:49
【问题描述】:

我正在尝试通过 OpenCL 开发一个可以同时利用 CPU 和 GPU 的应用程序。具体来说,我有两个内核,一个用于 CPU 执行,一个用于 GPU。 CPU内核会改变一个缓冲区的内容,当GPU检测到缓冲区被CPU改变时,GPU会做其他事情。

__kernel void cpuKernel(__global uint * dst1,const uint size)
{
    uint tid  = get_global_id(0);
    uint size = get_global_size(0);

    while(tid < size)
    {
        atomic_xchg(&dst1[tid],10);

        tid += size;
    }
}

__kernel void gpuKernel(__global uint * dst1, __global uint * dst2, const uint size)
{
    uint tid = get_global_id(0);
    uint size = get_global_size(0);

    while(tid < vectorSize)
    {
        while(dst1[vectorOffset + tid] != 10)
            ;

        dst2[vectorOffset + tid] = dst1[vectorOffset+tid];
        tid += size;
    }
}

如上所示,cpuKernel会将dst1缓冲区的每个元素都更改为10,相应地,GPU检测到这种变化后,会将元素值(10)分配到另一个缓冲区dst2的相同位置。 cpuKernel 在与 CPU 设备关联的 command1 中排队,而 gpuKernel 在与 GPU 设备关联的 command2 中排队,两个命令队列已设置 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE 标志。 然后我提出两种情况: 案例一:

clEnqueueNDRangeKernel(command2,gpuKernel);
clEnqueueNDRangeKernel(command1,cpuKernel);
clfinish(command1);
clfinish(command2);

案例2:

clEnqueueNDRangeKernel(command1,cpuKernel);
clfinish(command1);
clEnqueueNDRangeKernel(command2,gpuKernel);
clfinish(command2);

但结果显示,两种情况消耗的时间几乎相同,但我预计情况1会有一些重叠,但没有。谁能帮我?谢谢!

或者,任何人都可以帮助解释如何在 OpenCL 中实现在两个设备上异步运行的两个内核?

【问题讨论】:

    标签: asynchronous opencl


    【解决方案1】:

    你的要求太高了。您可能已经注意到,缓冲区对象与上下文相关,而命令队列与设备相关。 如果内核对缓冲区对象进行操作,则相应的数据必须在此设备上。如果您不使用 clEnqueueWriteBuffer() 显式传输它,OpenCL 将为您完成。

    因此,如果您在一个设备(例如 CPU)上使用内核修改缓冲区对象,然后在另一个设备(例如 GPU)上修改,OpenCL 驱动程序将等待第一个内核完成,传输数据,然后运行第二个内核。

    【讨论】:

    • 谢谢,但我对你的观点有疑问。首先,我使用零拷贝缓冲区,它被视为 CPU 和 GPU 的一个拷贝,我认为不需要拷贝。第二,你说相应的数据必须在那个设备上,但是我用的是AMD Fusion APU,主存是CPU和GPU共享的,即物理上只有一个内存。所以也许我应该换个方式问:对于AMD Fusion APU,零拷贝区域的缓冲区在CPU和GPU之间总是一致的,或者OpenCL实现是否会制作这个缓冲区的两个副本并在某个同步点之后使其保持一致?跨度>
    • 好吧,我不知道你用的是 AMD Fusion APU。我的回答是基于我在 nvidia gpu 和 opencl 实现方面的经验。我没有使用 AMD Fusion 的经验。但是,您的 OpenCL 实现可能不允许两个不同的命令队列同时访问同一个缓冲区。也许你可以通过使用两个不同的缓冲区来测试它(尽管它违背了你的目的)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-22
    • 2016-02-03
    • 2017-06-09
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 2017-08-07
    相关资源
    最近更新 更多