opengl - 损坏的 GLSL Spinlock/GLSL Locks Compendium

标签 opengl atomic spinlock

我有一个设置,我需要锁定、读取一些数据、处理、写入一些数据,然后解锁。为此,我制作了一个锁定纹理为 layout(r32ui) coherent uniform uimage2D .临界区的数据也以类似方式声明。

不幸的是,我对自旋锁的所有尝试都不能防止竞争条件,从而导致不正确的结果。我尝试了几种不同的方法。

我想我会收集我能找到的关于 GLSL 锁定的所有信息,以及我的结果 (GTX 580M)。我在这个详尽的列表中添加了一个社区 Wiki 答案。我将不胜感激对每个提出的可能问题的编辑/评论,最终创建一个有效方法列表。

最佳答案

我已将锁定纹理标准化为 img0 .

锁类型 1:

线程扭曲有一个共享的程序计数器。如果单个线程抢占锁,warp 中的其他线程仍将卡在循环中。实际上,这可以编译但会导致死锁。

示例:StackOverflow , OpenGL.org

while (imageAtomicExchange(img0,coord,1u)==1u);

//<critical section>
memoryBarrier();

imageAtomicExchange(img0,coord,0);

锁类型 2:

要解决类型 1 的问题,可以改为有条件地写入。在下面,我有时将循环编写为 do-while 循环,但 while 循环也无法正常工作。

锁类型 2.1:

尝试的第一件事是一个简单的循环。显然由于错误的优化,这可能会导致崩溃(我最近没有尝试过)。

示例:NVIDIA
bool have_written = false;
while (true) {
    bool can_write = (imageAtomicExchange(img0,coord,1u)!=1u);

    if (can_write) {
        //<critical section>
        memoryBarrier();

        imageAtomicExchange(img0,coord,0);
        break;
    }
}

锁类型 2.2:

上面的例子使用 imageAtomicExchange(...) ,这可能不是人们尝试的第一件事。最直观的是imageAtomicCompSwap(...) .不幸的是,由于错误的优化,这不起作用。它(应该)否则听起来。

示例:StackOverflow
bool have_written = false;
do {
    bool can_write = (imageAtomicCompSwap(img0,coord,0u,1u)==0u);

    if (can_write) {
        //<critical section>
        memoryBarrier();

        imageAtomicExchange(img0,coord,0);
        have_written = true;
    }
} while (!have_written);

锁类型 2.3:

imageAtomicCompSwap(...) 切回至 imageAtomicExchange(...)是另一个常见的变体。与 2.1 的区别在于循环终止的方式。这对我来说不起作用。

示例:StackOverflow , StackOverflow
bool have_written = false;
do {
    bool can_write = (imageAtomicExchange(img0,coord,1u)!=1u);

    if (can_write) {
        //<critical section>
        memoryBarrier();

        imageAtomicExchange(img0,coord,0);
        have_written = true;
    }
} while (!have_written);

关于opengl - 损坏的 GLSL Spinlock/GLSL Locks Compendium,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21538555/

相关文章:

C++ std::atomic - 不可能基于共享原子变量同步 2 个线程

locking - 非抢占式 linux 内核上的 spin_lock

cpu - 什么时候使用自旋锁是个好主意?

kernel - 为什么linux在内核代码持有自旋锁后禁用内核抢占?

opengl - OpenGL 中的 PNG 格式?

c++ - store(x,std::memory_order_relaxed)与直接分配值之间的区别

无法在其他计算机上运行由Visual Studio 2010编译的opengl程序

C++ 创建原子函数

c++ - opengl c++ 代码中的错误,可能与 cood 系统有关

java - JOGL调试: DebugGL usage