Kernel OpenCL内核中的原子操作

Kernel OpenCL内核中的原子操作,kernel,opencl,atomic,gpu-atomics,Kernel,Opencl,Atomic,Gpu Atomics,当我试图找到内核中原子操作的更多细节时,我发现了一些奇怪的事情。据我所知,当对一个数字使用原子操作时,来自所有线程的所有此类操作都将被序列化以在此数字上启动,以保持完整性。以下是我的一段内核代码: if(atomic_cmpxchg(&A[ptr],0,-1) == -1) ptr = A[ptr + 3]; //To delay uint k = 1000000; while(k--); A[ptr + 3] = newVal

当我试图找到内核中原子操作的更多细节时,我发现了一些奇怪的事情。据我所知,当对一个数字使用原子操作时,来自所有线程的所有此类操作都将被序列化以在此数字上启动,以保持完整性。以下是我的一段内核代码:

    if(atomic_cmpxchg(&A[ptr],0,-1) == -1)
        ptr = A[ptr + 3];

    //To delay
    uint k = 1000000;
    while(k--);

    A[ptr + 3] = newValue;
对于上面的代码,假设只有两个线程T1和T2。据我所知,T1和T2都将执行代码段,但当它们尝试执行原子_cmpxchg操作时,T2必须等待T1完成(假设T1首先运行)。正如我设计的,当T1读取[ptr]时,[ptr]的旧值为0,因此它将原子地更改为-1。之后,因为对于T1,条件不满足,所以T1将直接转到延迟代码并被延迟。现在是T2处理[ptr]的时候了,因为现在[ptr]被设置为-1,所以T2的条件满足,所以T2将运行到“ptr=A[ptr+3];”。但我的问题是:因为T2完成条件判断后,会立即执行“ptr=A[ptr+3];”,但是T1遇到延迟,所以A[ptr+3]的值还没有被T1更新(因为k太大,延迟会很长)。因此T2不会读取[ptr+3]的最新值,该值应该是newValue。但我的实验表明,无论我设置的k值有多大,结果总是正确的,即T2始终可以读取正确的值(newValue),无论T1遇到多长延迟。有人能帮忙调查这个案子吗?非常感谢

  • 编译器可能足够聪明,能够发现“延迟”循环没有副作用,并完全优化它

  • 在GPU上,来自同一工作组的OpenCL工作项通常会运行(至少在一定程度上,取决于具体的硬件)。这意味着两个线程同时执行同一条指令。它们基本上共享一个指令指针。在控制流发散的情况下,每个线程都会记住它当前是否处于活动状态,并且仅在当前指令处于活动状态时才执行它。原子操作仍然是序列化的