Glsl 计算着色器是否可以从多个线程将相同的值写入相同的共享内存?

Glsl 计算着色器是否可以从多个线程将相同的值写入相同的共享内存?,glsl,compute-shader,Glsl,Compute Shader,我想通过使用一个bool变量(而不是数组)模拟计算着色器中的布尔约简,方法是使用所有线程都可以看到的false值初始化变量,然后让每个线程通过将其写入变量来为约简贡献一个true值,或者通过不执行任何操作来贡献false值 例如: shared bool someNumberIsBig; // ... void main() { uint id = gl_LocalInvocationID.x; uint gid = gl_GlobalInvocationID.x;

我想通过使用一个
bool
变量(而不是数组)模拟计算着色器中的布尔约简,方法是使用所有线程都可以看到的
false
值初始化变量,然后让每个线程通过将其写入变量来为约简贡献一个
true
值,或者通过不执行任何操作来贡献
false

例如:

shared bool someNumberIsBig;

// ...

void main()
{
    uint id = gl_LocalInvocationID.x;
    uint gid = gl_GlobalInvocationID.x;

    if (id == 0) someNumberIsBig = false;
    memoryBarrierShared();
    barrier();

    uint oneNumber = someBuffer[gid];

    if (oneNumber > 5) someNumberIsBig = true; // WOW that's big
    memoryBarrierShared();
    barrier();

    if (someNumberIsBig)
    {
        // do some work, with dynamic uniformity even, and with an
        // assurance that at least one number was indeed big...  or not??
    }
}
这对我来说似乎很简单,但可能竞争写入同一位置会导致某种问题。我是否依赖于任何未定义或特定于实现的行为


(我想做的另一种方法是将所有布尔值写入一个共享数组,然后在该数组上运行一个显式的约简算法。我的直觉天真地告诉我,这将比上面的算法慢,但也许它不会真的…无论如何,我只是在问上面的算法是否正确,不管它的效率如何

共享内存总是很昂贵的。你们可以从这篇文章中找到很好的解释

但是,如果您仍然希望使用共享内存,则它是受支持的。它们唯一的问题是内存和执行顺序不一致。但您的示例使用内存屏障和执行屏障解决了这两个问题。如果您希望使用共享内存执行更复杂的操作,则必须使用原子内置函数。有关详细信息,请参阅