图形着色器分析技术

5

相当长的一段时间里,我一直避免在我的着色器代码中使用分支结构,而是通过将

float invert_value(in float value)
{
if(value == 0.0)
    return 0.0;
else
    return 1.0 / value;
}

写出像这样的“聪明”代码
float invert_value_ifless(in float value)
{
float sign_value = sign(value);
float sign_value_squared = sign_value*sign_value;
return sign_value_squared / ( value + sign_value_squared - 1.0); 
}

这个函数与第一个函数完全相同,没有分支,因此速度更快。

但是,真的是这样吗?我在这里跟幽灵打架了吗?

如何对图形着色器进行速度分析?我最感兴趣的是最近的移动平台(Android),但任何关于图形分析的建议都受欢迎!


1
"我是在和幽灵战斗吗?" [是的,你是。] (https://dev59.com/yFoU5IYBdhLWcg3wG0Ky) - Nicol Bolas
Nicol,你的回答非常出色。 - Leszek
这也是在与幽灵作斗争吗?与其写成if(a>0) b=(1-a)/(2-a) else b=(1+a)/(2+a)不如写成signA=sign(a); b = (1-signAa)/(2-signAa); - Leszek
除非你手头有真正准确的分析数据,否则那些所谓的过早优化只会让代码更难读懂和理解。 - Nicol Bolas
2个回答

2
通常,GPU通常被实现为非常宽的SIMD处理器,因此对于每个像素执行相同操作可以同时处理很多像素,而选择每个像素不同操作会使计算变得更加困难。这就是为什么GLSL中会使用 step 等操作。一个好的GLSL编译器通常可以消除编译时的条件性,并且可能能够通过其他方式使您的分支代码成为非分支代码,但是GLSL编译器通常不像普通离线语言编译器那样好,因为它们有自己的性能预算需要考虑。
我是一名iOS开发人员,所以我可以详细谈论Xcode帧分析器的奇妙之处,并为完整的答案做出贡献,但我很抱歉无法提供有关Android的信息。
在Xcode中,有一个帧捕获按钮。按下它,将捕获单个帧的完整OpenGL命令流。从那里,您将能够检查每个OpenGL命令之前和之后的所有状态和缓冲区。将报告每个调用所花费的时间。更好的是,您的GLSL代码本身将被剖析到行级别-将报告每行代码的微秒数。并且,真正超越边缘的是,您可以直接在那里重新编写您的GLSL代码,并重新运行捕获的帧,以查找成本的变化。或者只是作为快速反馈的GLSL创作环境,虽然这并不是该工具的实际用途。

0

所有主要的Android GPU制造商都有自己的GPU分析工具,大致与XCode的帧捕获相同。ARMQualcommPowerVR都有。

这些东西必须被测量,不幸的是,由于Android用户由于各种原因没有更新,所以野外驱动程序的质量是不稳定的。


是的,我正在尝试使用Adreno Profiler ATM,但是当我将其连接到我的手机时,出现了“无法找到启用Adreno Profiler的应用程序”的错误。我会继续尝试 :) - Leszek
是的,我的GPU性能分析工具使用经验通常很令人沮丧。如果你想要捷径,我知道PowerVR的着色器编辑器可以估算各种GPU架构的周期计数,而无需在设备上运行着色器(我预计其他供应商也有类似的功能,但我不确定)。这可能足以给你一个概念。 - Columbo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接