2016-06-14 160 views
0

計算着色器如何劃分任務?如何用計算着色器劃分任務?

#version 430 core 
layout (local_size_x = 64) in; 


layout(std430, binding=4) buffer INFO 
{ 
     vec2 info[]; 
}; 


void main() 
{ 

    uint gid = gl_GlobalInvocationID.x; 
    info[gid].x += 1.0; 
    info[gid].y += 1.0; 
    memoryBarrier(); 
} 
在這個例子中

,通過指定local_size_x = 64,是否意味着每個工作組將自動擁有64個線程,並且由於輸入是VEC2陣列,它知道剛剛經過主與每個VEC2上一個單獨的線程?

另外,如果着色器爲每個vec2輸入生成10個vec2,然後我想在每個獨立的線程上做一些不同的操作,我該怎麼做。最初的64個線程將分支到640.這可以在這個相同的着色器中完成,或者我必須做第二個?

回答

0
在這個例子中

,通過指定local_size_x = 64,是否意味着每個工作組將自動擁有64個線程,並且由於輸入是VEC2陣列,它知道剛剛經過主與一每VEC2單獨的線程?

是的,這就是invocations within a work group are defined

另外,如果着色器爲每個vec2輸入生成10個vec2,然後我想在每個獨立線程上做一些不同的操作,我會怎麼做。

你怎麼做完全取決於你。但是,是的,它必須是一個不同的着色器。計算着色器不能創建調用。不直接。

在工作組中有工作項的目的是允許這些本地調用相互通信並幫助他們計算某些內容。如果您沒有任何shared variables or barrier calls,那麼它的本地大小並不重要(當然,不是從功能角度來看,本地大小可能會影響性能)。

因此,您應該根據您打算在特定調度操作中推進多少工作來選擇當地規模。現在,您必須以整數倍數64處理vec2 s。如果同一組的多個調用正在讀取相同的值,則需要重新評估整個組將執行多少工作。

對工作組內調用次數的限制是依賴於硬件的,但不會少於1024.所以你有一些空間可以玩。

在你的新系統中,如果你仍然想要一個工作組調用來處理64個輸入,那麼顯然一個工作組必須有一個總共640的本地大小。我可能會建議像8這樣的更小的粒度,讓你的本地大小總共爲80.

無論您選擇什麼尺寸,實際指定此尺寸的最佳方法是使用本地尺寸具有多個尺寸的事實。 X維度應該引用輸入索引,Y維度是來自X輸入的輸出索引。所以Y尺寸是10,X尺寸是8或64或者任何你想要的。

因此,當你去獲取你的輸入,你需要的指數爲:

const uvec3 size_mult = {1, gl_NumWorkGroups.x, gl_NumWorkGroups.x * gl_NumWorkGroups.y}; 
const uint input_index = gl_WorkGroupSize.x * dot(gl_WorkGroupID, size_mult) + gl_LocalInvocationID.x; 

爲輸出的指數爲:

const uint output_index = gl_WorkGroupSize.y * input_index + gl_LocalInvocationID.y;