GLES คำนวณการทำงานของอะตอมมิกเชเดอร์สำหรับการลอยตัว

ฉันใช้คอมพิวเตอร์เชเดอร์เพื่อรับค่าผลรวม (ประเภทคือลอย) เช่นนี้

#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 เป็น int ได้หรือมีวิธีง่ายๆ ในการแก้ปัญหาของฉันบ้างไหม?


person KaguyaSan    schedule 13.01.2020    source แหล่งที่มา


คำตอบ (1)


โดยทั่วไปอะตอมมิกส์จะมีประสิทธิภาพต่ำมาก โดยเฉพาะอย่างยิ่งหากมีการโต้แย้งอย่างหนักจากการเข้าถึงแบบขนานจากเธรดจำนวนมาก ดังนั้นฉันจะไม่แนะนำพวกเขาสำหรับกรณีการใช้งานนี้

เพื่อรักษาความเท่าเทียมไว้ตรงนี้ คุณต้องมีกลยุทธ์การลดหลายรอบจริงๆ รหัสเทียม บางอย่างเช่นนี้:

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 หรือแม้แต่ตัวกรองเชิงเส้นแบบธรรมดาเพื่อโหลดตัวอย่างหลายตัวอย่างในการดำเนินการสร้างพื้นผิวครั้งเดียว)

person solidpixel    schedule 15.01.2020