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

标签 c++ opengl arm

我想知道 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)),就好像存在某种竞争条件一样。

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

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

  • 您对此有何看法?谢谢

最佳答案

It happens that b is different from execution to execution (glDispatchCompute(1, 100, 1)) as if there is some race condition.

那是因为有一个:

a[tid % 16] += 1;

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

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

现在,您可以通过 atomic operations 操作 a :

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

这是明确定义的行为。


I am not sure wether threads within a work group are really concurrent (like warps in a streaming multiprocessor).

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

Also how many cores are mapped to work groups/shaders?

同样,本质上是无关紧要的。这对于性能而言很重要,但这主要是关于本地团队规模的大小。但就您的代码是否有效而言,这并不重要。

关于c++ - OpenGL计算着色器中线程的执行顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41667701/

相关文章:

C++98/03 引用折叠和 cv 限定符

c++ - c_str() ing 字符串 - 除了第一行之外的所有其他行都将丢失

c++ - 从方法非确定性行为返回 std::string?

c - 整数不作为对 Swift 中函数的引用传递

linux - 从 x_64 为 ARM 交叉编译 Chrome 时出错

基于 Windows 8 ARM 的平板电脑上的 VB6

c++ - C++中的简单探路者

c++ - 使用 libcurl 的跨平台 C++

c++ - 设置GL_TEXTURE_2D_ARRAY,帧缓冲区不完整

linux - 如何统计ARM程序执行的指令数?