GLES menghitung operasi atom shader untuk float

Saya menggunakan shader komputer untuk mendapatkan nilai penjumlahan (tipenya float) seperti ini:

#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
}

Saya tahu ada operasi atom seperti atomAdd(), tetapi tidak mendukung parameter float, dan penghalang() yang sepertinya tidak menyelesaikan masalah saya. Mungkin saya dapat memasukkan float ke int, atau adakah cara sederhana untuk menyelesaikan masalah saya?


person KaguyaSan    schedule 13.01.2020    source sumber


Jawaban (1)


Atom secara umum sangat buruk dalam hal kinerja, terutama jika sangat terhambat oleh akses paralel dari banyak thread, jadi saya tidak akan merekomendasikannya untuk kasus penggunaan ini.

Untuk menjaga paralelisme di sini, Anda benar-benar memerlukan semacam strategi pengurangan multi-pass. Kode semu, kira-kira seperti ini:

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

Ini adalah pengurangan sederhana 2:1, sehingga memberikan kinerja O(log2(N)), tetapi Anda dapat melakukan lebih banyak pengurangan per pass untuk mengurangi bandwidth memori penyimpanan perantara. Untuk GPU yang menggunakan tekstur sebagai input 4:1 cukup bagus (Anda dapat menggunakan textureGather atau bahkan filter linier sederhana untuk memuat banyak sampel dalam satu operasi tekstur).

person solidpixel    schedule 15.01.2020