作为 GLSL 着色器的新手,我在旧上网本上注意到,向完美运行的着色器添加一行代码可能会突然使执行时间增加数千倍。
例如,当 limit
的值为 32 或以下时,该片段着色器会立即运行,而一旦 limit
的值为 33,则需要 10 秒才能运行:
int main()
{
float limit=33.;//runs instantly if =32.
float useless=0.5;
for(float i=0.;i<limit;i++) useless=useless*useless;
gl_FragColor=useless*vec4(1.,1.,1.,1.);
}
同样让我困惑的是,在 32 圈循环中添加一个或多个无用
自乘不会导致时间急剧增加。
这是一个没有 for 循环的示例。在我的计算机上,它在一毫秒内运行了 6 个 sin
计算,而添加第七个 sin 突然使程序需要大约 500 毫秒才能运行:
int main()
{
float useless=gl_FragCoord.x;
useless=sin(useless);
useless=sin(useless);
useless=sin(useless);
useless=sin(useless);
useless=sin(useless);
useless=sin(useless);
useless=sin(useless);//the straw that breaks the shader's back
gl_FragColor=useless*vec4(1.,1.,1.,1.);
}
在我拥有的一台不太过时的计算机上,在我找到这样的断点之前,编译时间变得太大。
在我的上网本上,我预计运行时间会随着我添加操作而不断增加。
我想知道是什么导致了这些突然的飞跃,因此这是否是我应该解决的问题,计划针对相当广泛的 Steam 受众。如果有用的话,这是我正在做测试的上网本 http://support.hp.com/ch-fr/document/c01949780及其芯片组http://ark.intel.com/products/36549/Intel-82945GSE-Graphics-and-Memory-Controller
另外,我不知道这是否重要,但我正在使用 SFML 来运行着色器。
最佳答案
根据intel ,GMA 950 在硬件上支持着色器模型 2,在软件上支持着色器模型 3。根据microsoft ,着色器模型 2 对指令数量有相当严格的限制(64 个 ALU 和 32 个 tex 指令)。
我的猜测是,当指令数量超过此数量时,英特尔驱动程序会决定在软件中进行着色,这将与您所看到的糟糕性能相匹配。
sin 函数可能会扩展到多条指令。循环可能会展开,从而导致更高的指令数和更高的限制。我不知道为什么在循环外添加第 33 次乘法不会触发此操作。
要决定是否应该修复此问题,我可以推荐 unity hardware stats和 steam hardware survey 。简而言之,我想说着色器模型 2 不是您需要支持的:)
关于performance - 是什么导致了 GLSL 着色器的性能突破点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38767472/