Asynchronous OpenCL中两个命令队列中命令的异步执行

Asynchronous OpenCL中两个命令队列中命令的异步执行,asynchronous,opencl,Asynchronous,Opencl,我正在尝试通过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);

我正在尝试通过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;
    }
}
案例2:

clEnqueueNDRangeKernel(command1,cpuKernel);
clfinish(command1);
clEnqueueNDRangeKernel(command2,gpuKernel);
clfinish(command2);
但结果表明,两种情况下所消耗的时间几乎相同,但我预计在情况1中会有一些重叠,但实际情况并非如此。有人能帮我吗?谢谢


或者,有人能解释一下如何在OpenCL中实现两个在两个设备上异步运行的内核吗?

你要求太多了。您可能已经注意到,缓冲区对象与上下文相关,而命令队列与设备相关。 如果内核操作缓冲区对象,则相应的数据必须在此设备上。如果您不使用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实现可能不允许两个不同的命令队列同时访问同一缓冲区。也许您可以通过使用两个不同的缓冲区来测试这一点(尽管这与您的目的背道而驰)。
clEnqueueNDRangeKernel(command1,cpuKernel);
clfinish(command1);
clEnqueueNDRangeKernel(command2,gpuKernel);
clfinish(command2);