AMD からGPU ShaderAnalyzerをダウンロードし、次の GLSL プログラムをフィードしました。
uniform mat4 ModelViewMatrix;
attribute vec4 VertexPosition;
void doSomething1(void) {
gl_Position = ModelViewMatrix * VertexPosition;
}
void doSomething2(void) {
gl_Position = ModelViewMatrix * VertexPosition;
}
void main(void) {
doSomething1();
doSomething2();
}
これにより、Radeon HD 2400 から Radeon HD 6970 までのすべてのカードで次の分解 (または同等のもの) が生成されました。
; -------- Disassembly --------------------
00 CALL_FS NO_BARRIER
01 ALU: ADDR(32) CNT(16) KCACHE0(CB0:0-15)
0 x: MUL ____, R1.w, KC0[3].w
y: MUL ____, R1.w, KC0[3].z
z: MUL ____, R1.w, KC0[3].y
w: MUL ____, R1.w, KC0[3].x
1 x: MULADD R127.x, R1.z, KC0[2].w, PV0.x
y: MULADD R127.y, R1.z, KC0[2].z, PV0.y
z: MULADD R127.z, R1.z, KC0[2].y, PV0.z
w: MULADD R127.w, R1.z, KC0[2].x, PV0.w
2 x: MULADD R127.x, R1.y, KC0[1].w, PV1.x
y: MULADD R127.y, R1.y, KC0[1].z, PV1.y
z: MULADD R127.z, R1.y, KC0[1].y, PV1.z
w: MULADD R127.w, R1.y, KC0[1].x, PV1.w
3 x: MULADD R1.x, R1.x, KC0[0].x, PV2.w
y: MULADD R1.y, R1.x, KC0[0].y, PV2.z
z: MULADD R1.z, R1.x, KC0[0].z, PV2.y
w: MULADD R1.w, R1.x, KC0[0].w, PV2.x
02 EXP_DONE: POS0, R1
03 EXP_DONE: PARAM0, R0.____
04 ALU: ADDR(48) CNT(1)
4 x: NOP ____
05 NOP NO_BARRIER
END_OF_PROGRAM
doSomething2()
次に、メソッド内の関数とその呼び出しをコメントアウトしましたmain
。結果はまったく同じでした。AMD のツールのすべてのシェーダーが冗長な計算を最適化しました。したがって、この質問に対する答えは「はい」です。一般的なケースでは、GLSL コンパイラはこの最適化を実行するのに十分なほどスマートですが、@nicol-bolas がコメントで指摘した注意事項があります。これがすべてのコンパイラに当てはまるという 100% の保証はありません。もちろん、最も安全な方法は、可能な限りそのような最適化を自分で実行することですが、何らかの理由で最適化を実行できない場合は、これが当てはまります。
更新: Cg (NVIDIA のコンパイラの 1 つ) の下で、2 番目の関数呼び出しをコメント アウトして、またはコメント アウトせずに、同じプログラムをコンパイルしました。どちらの場合も、次の結果が生成されました。
mul r0, v0.y, c1
mad r0, v0.x, c0, r0
mad r0, v0.z, c2, r0
mad oPos, v0.w, c3, r0
そうです、NVIDIA もそれを最適化します。少なくとも、Cg コンパイラは最適化します。Cg でコンパイルされたコードが Intel GPU で実行されるという主張を見つけましたが、これは私の専門知識の範囲外です。
誰かがこれにテスト ケースを追加したい場合は、お気軽にどうぞ。ただし、この時点で、質問に対する適切な回答が得られたと感じています。