【问题标题】:GLES compute shader atomic operations for floatGLES 计算浮点数的着色器原子操作
【发布时间】:2020-01-13 12:59:38
【问题描述】:

我正在使用计算机着色器来获取总和值(类型为浮点数),如下所示:

#version 320 es
layout(local_size_x = 640,local_size_y=480,local_size_z=1)
layout(binding = 0) buffer OutputData{
float sum[];
}output;
uniform sampler2D texture_1;
void main()
{
    vec2 texcoord(float(gl_LocalInvocationIndex.x)/640.0f,float(gl_LocalInvocationIndex.y)/480.0f);
    float val = textureLod(texture_1,texcoord,0.0).r;
//where need synchronize
    sum[0] = sum[0]+val;
//Here i want to get the sum of all val in texture_1 first channal
}

我知道有 atomicAdd() 之类的原子操作,但不支持 float 参数,并且 barrier() 似乎无法解决我的问题。 也许我可以将浮点数编码为 int,或者有什么简单的方法可以解决我的问题?

【问题讨论】:

    标签: android opengl-es synchronization compute-shader glsles


    【解决方案1】:

    Atomics 在性能方面通常很差,尤其是在大量线程的并行访问严重竞争的情况下,因此我不建议将它们用于此用例。

    要在这里保持并行性,您确实需要某种多通道减少策略。伪代码,类似这样:

    array_size = N
    data = input_array
    
    while array_size > 1:
       spawn pass with M = array_size/2 threads.
       thread M: out[M] = data[2*M] + data[2*M+1]
       array_size = M
       data = out
    

    这是一个简单的 2:1 缩减,因此提供 O(log2(N)) 性能,但您可以在每次通过时进行更多缩减以减少中间存储的内存带宽。对于使用纹理作为输入的 GPU,4:1 非常好(您可以使用 textureGather 甚至简单的线性过滤器在单个纹理操作中加载多个样本)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-07
      • 1970-01-01
      • 2014-01-25
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 2022-11-18
      相关资源
      最近更新 更多