GLES вычисляет шейдерные атоми c операции для float - PullRequest
0 голосов
/ 13 января 2020

Я использую компьютерный шейдер для получения значения суммы (тип 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
}

Я знаю, что есть такие операции atomi c, как atomicAdd (), но они не поддерживают параметр float, и барьер (), который, похоже, не решает мою проблему. Может быть, я могу преобразовать float в int, или есть какой-то простой способ решить мою проблему?

1 Ответ

1 голос
/ 15 января 2020

Атомика, как правило, очень плоха с точки зрения производительности, особенно если сильно нагружена параллельным доступом из множества потоков, поэтому я бы не рекомендовал их для этого варианта использования.

Чтобы сохранить здесь параллелизм, вам действительно нужна какая-то многопроходная стратегия сокращения. Псевдокод, что-то вроде этого:

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)), но вы можете сделать большее сокращение за проход, чтобы уменьшить пропускную способность памяти промежуточное хранение. Для графического процессора использование текстур в качестве входных данных 4: 1 очень удобно (вы можете использовать textureGather или даже простой линейный фильтр для загрузки нескольких выборок за одну операцию текстурирования).

...