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