Optimization 跨函数冗余赋值的GLSL编译器优化
我已经了解到GLSL(特别是v1.0.17:我的应用程序在WebGL下运行)编译器将优化冗余分配,例如:Optimization 跨函数冗余赋值的GLSL编译器优化,optimization,compiler-construction,glsl,webgl,Optimization,Compiler Construction,Glsl,Webgl,我已经了解到GLSL(特别是v1.0.17:我的应用程序在WebGL下运行)编译器将优化冗余分配,例如: gl_FragCoord = ProjectionMatrix * ModelViewMatrix * VertexPosition; . . . gl_FragCoord = ProjectionMatrix * ModelViewMatrix * VertexPosition; 编译器是否足够聪明,可以跨函数调用执行相同的优化?例如: void doSomething1(void) {
gl_FragCoord = ProjectionMatrix * ModelViewMatrix * VertexPosition;
. . .
gl_FragCoord = ProjectionMatrix * ModelViewMatrix * VertexPosition;
编译器是否足够聪明,可以跨函数调用执行相同的优化?例如:
void doSomething1(void) {
. . .
gl_FragCoord = ProjectionMatrix * ModelViewMatrix * VertexPosition;
}
void doSomething2(void) {
. . .
gl_FragCoord = ProjectionMatrix * ModelViewMatrix * VertexPosition;
}
void main(void) {
doSomething1();
doSomething2();
}
我从AMD下载了,并将以下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的编译器之一)下编译了同一个程序,有注释也没有注释第二个函数调用,在这两种情况下,它都产生了以下结果:
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编译的代码在英特尔GPU上运行,但这超出了我的专业知识范围,所以就拿它来说吧
如果有人想在此基础上添加测试用例,请放心,但现在我觉得这个问题已经得到了适当的回答。这个问题无法回答。编译器优化是特定于编译器的,因此它们会随着新的驱动程序、新的硬件以及不同的硬件而改变。没有实际的答案。事实上,即使是第一种情况也是特定于硬件的,并且不受标准的保证。谢谢,但我的意思是,这是一个一般意义上的问题。很明显,每个编译都会根据自己的算法进行不同的优化(如果有的话)。-1:“是的:在一般情况下,GLSL编译器将足够聪明来执行此优化”这是怎么回事?您已经为一个编译器演示了它。英伟达会这么做吗?英特尔呢?尼科尔:我添加了使用NVIDIA的Cg编译器编译的结果,该编译器执行了相同的优化。这就是我要投入的全部精力。如果您仍然觉得它需要更多的审查,那么可以随意添加额外的测试。