[英]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.