我已将锁定纹理标准化为
img0
。
锁类型1:
线程绕组有一个共享的程序计数器。 如果单个线程获取了锁,则在同一绕组中的其他线程仍将被卡在循环中。 在实践中,这样编译可行但会导致死锁。
示例:StackOverflow,OpenGL.org
while (imageAtomicExchange(img0,coord,1u)==1u);
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) {
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) {
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) {
memoryBarrier();
imageAtomicExchange(img0,coord,0);
have_written = true;
}
} while (!have_written);