OpenGL/OpenCL中的gl_GlobalInvocationID, local_size_x的理解
最近在學習 Vulkan
,結果在檢視示例程式碼的時候,對於如下兩句出現了疑問:
layout(local_size_x = X, local_size_y = Y, local_size_z = Z) in;
ivec3 pos = ivec3(gl_GlobalInvocationID);
首先是 Invocation
這個單詞的理解,計算機語言中他的意思是 " the act of making a particular function start
" ,中文意思是 " 呼叫,啟用
"。
其中
layout(local_size_x = X, local_size_y = Y, local_size_z = Z) in;
意思是初始化, X * Y * Z
個計算單元供我們的程式碼呼叫,可以簡單理解成執行緒數。
而使用如下的程式碼
ivec3 pos = ivec3(gl_GlobalInvocationID);
意思是獲取當前程式碼執行的計算單元的編號,也可以理解成獲取當前執行緒的索引。
比如下面的程式碼,就是一個簡單的利用 gl_GlobalInvocationID
,進行平行計算的例子:
#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(); }
但是,如果傳入的陣列的大小超過我們設定的計算單元的數量的情況,上述的程式碼是處理不了的。
可以如下方式處理上述情況:
#version 430 layout (local_size_x = 64) in; uniform atomic_uint counter = 0; layout(std430, binding=4 ) buffer INFO { vec2 info[]; uint len; }; void main() { uint gid = atomicAdd(counter,1); if (gid <= len ) { info[gid].x += 1.0; info[gid].y += 1.0; memoryBarrier(); } }
如果想動態調整計算單元的數量,增加處理靈活性,可以參考下面的程式碼:
#version 450 //commented out previous definitions /*layout (constant_id = 0) const int TX = 512; layout (constant_id = 1) const int TY = 1; layout (constant_id = 2) const int TZ = 1; */ layout(local_size_x_id = 0) in; layout(local_size_y_id = 1) in; layout(local_size_z_id = 2) in; //rest of the shader
外部通過修改 TX
, TY
, TZ
的數值來動態調整所需要的計算單元的數量。
具體資訊,可以參考下圖:
相關介紹,請參考 ofollow,noindex" target="_blank">Compute Shader 。網頁如果打不開,可以點選下圖,檢視詳細內容:
參考連結
- opengl渲染管線 不能再詳細了
- / jessie / opengl-4-man-doc / gl_GlobalInvocationID(3G)
- 基於OpenGL ES的深度學習框架編寫
- How are tasks divided up with compute shaders?
- Vulkan ® 1.1.95 - A Specification (with all registered Vulkan extensions)
- Compute Shader
- User defined WorkGroup sizes in Vulkan Compute shaders
- Vulkan atomic counters
- Atomic Counter
- atomicAdd — perform an atomic addition to a variable