作为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圈循环中添加一个或多个useless
自乘 out 不会导致急剧增加的时间。
这是一个没有for循环的例子。它在我的计算机上运行了一毫秒,有6 sin
次计算,并且添加第七个突然使程序运行大约需要500ms:
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运行着色器。
答案 0 :(得分:4)
根据intel,GMA 950支持硬件中的着色器模型2,以及软件中的着色器模型3。根据{{3}},着色器模型2对指令计数有严格的限制(64 ALU和32 tex指令)。
我的猜测是,当超过此指令数时,英特尔驱动程序决定在软件中进行着色,这与您所看到的糟糕性能相匹配。
sin函数可以扩展为多个指令。循环可能会展开,从而导致更高的指令数量和更高的限制。为什么在循环外添加第33次乘法不会触发这个我不知道。
决定是否应该解决此问题,我可以推荐microsoft和unity hardware stats。总之,我会说着色器模型2不需要你支持:)