繁体   English   中英

OpenGL计算着色器中线程的执行顺序

[英]Execution order of threads in OpenGL compute shader

我想知道OpenGL中线程的执行顺序。

假设我有一个移动GPU,其n_cores通常在8到32之间(例如ARM Mali )。 这意味着它们与Nvidia(AMD)扭曲(波阵面)不同。

我问的原因是由于以下玩具示例

layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;

shared float a[16];

void main() {
    uint tid = gl_GlobalInvocationID.x; // <-- thread id

    // set all a to 0
    if (tid < 16) {
        a[tid] = 0;
    }
    barrier();
    memoryBarrierShared();

    a[tid % 16] += 1;

    barrier();
    memoryBarrierShared();

    float b = 0;
    b = REDUCE(a); // <-- reduction of a array a
}

  • 碰巧b在执行之间是不同的( glDispatchCompute(1, 100, 1)glDispatchCompute(1, 100, 1) ),就好像存在某种竞争条件一样。

  • 我不确定工作组中的线程是否真的是并发的(就像流式多处理器中的扭曲一样)。

  • 还有多少个核心映射到工作组/着色器?

  • 您对此有何看法? 谢谢

碰巧b在执行之间是不同的( glDispatchCompute(1, 100, 1)glDispatchCompute(1, 100, 1) ),就好像存在某种竞争条件一样。

那是因为有一个:

a[tid % 16] += 1;

对于本地大小为256的工作组,该工作组中将至少有两个调用的tid % 16值相同。 因此,这些调用将试图操纵同一索引a

由于没有障碍或任何其他机制,以防止这种情况,那么这是对的元素的竞争条件a 因此,您得到未定义的行为。

现在,您可以通过原子操作来操纵a

atomicAdd(a[tid % 16], 1);

这是定义明确的行为。


我不确定工作组中的线程是否真的是并发的(就像流式多处理器中的扭曲一样)。

这无关紧要。 您必须将它们视为同时执行。

还有多少个核心映射到工作组/着色器?

再次,本质上无关紧要。 这在性能方面很重要,但这主要是关于使本地小组规模变大。 但是就您的代码是否有效而言,这无关紧要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM