繁体   English   中英

GLES 计算浮点的着色器原子操作

[英]GLES compute shader atomic operations for float

我正在使用计算机着色器来获得这样的总和值(类型为浮点数):

#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() 这样的原子操作,但不支持浮点参数,而 barrier() 似乎不能解决我的问题。 也许我可以将浮点数编码为 int,或者有什么简单的方法可以解决我的问题?

原子在性能方面通常很差,特别是如果来自大量线程的并行访问严重竞争,所以我不会在这个用例中推荐它们。

为了保持并行性,您确实需要某种多遍减少策略。 伪代码,类似这样:

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 甚至一个简单的线性过滤器在单个纹理操作中加载多个样本)。

暂无
暂无

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

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