如何对WebGL着色器进行基准测试?

9

我们可以通过在一秒钟内调用JavaScript普通函数的次数来测试其性能。但是,在WebGL中,像gl.drawArrays这样的函数是异步的,因此无法通过测试API调用的时间来测量着色器所需的时间。

那么有没有办法来测试WebGL函数的性能呢?

2个回答

4

由于着色器的上下文非常复杂且非常特定于GPU,因此很难对其进行基准测试。

您可以在使用某个着色器绘制大量的东西(几千到几百万次绘制调用)之前和之后使用performance.now,然后通过调用gl.readPixels来阻塞GPU,以判断一个着色器是否比另一个快。它会告诉你哪个更快。但是它不会告诉您它们有多快,因为阻塞GPU包括起始和阻塞时间。

想象一辆赛车。对于直线赛车,您计时加速度到达目的地。对于赛车,您计时以全速完成的一圈。您让车先行驶一圈,然后计时第二圈,车以全速穿过起点和终点。因此,您可以得出车的速度,而对于直线赛车,您获得了它的加速度(通常与GPU无关,因为如果您追求速度,则永远不应该启动和停止它们)。

另一种在不添加启动/停止时间的情况下计时的方法是在requestAnimationFrame帧之间绘制一堆东西。不断增加数量,直到帧之间的时间跳跃了整个帧。然后比较着色器之间的数量。

实际使用中还有其他问题。例如,像许多移动设备上的PowerVR这样的瓦片GPU会尝试剔除将被覆盖的基元的部分。因此,在非瓦片GPU上具有大量重叠绘制的重型着色器可能在瓦片GPU上非常快。

此外,请确保您正在计时正确的内容。如果您正在计时顶点着色器,则可能希望将画布设置为1x1像素,将片段着色器尽可能简单,并传递许多顶点以进行一次绘制调用(以消除调用时间)。如果您正在计时片段着色器,则可能需要一个大画布和一组包含几个完整画布四边形的顶点。

还请参见WebGL/OpenGL:性能比较


3
没有确切的方法可以获取着色器执行时间,除非使用一些特定于GPU厂商的工具。但是,除了gman的建议之外,还有一个名为EXT_disjoint_timer_query的扩展,它允许测量绘制调用的执行时间,这在很大程度上取决于着色器执行时间,尤其是当您的着色器非常复杂时(因此占用了GPU执行绘制调用的大部分时间)。

EXT_disjoint_timer_query在像PowerVR(iOS)这样使用延迟渲染器的平铺架构上不会提供有用的信息,它们能做的最好的事情就是在所有多边形被分割、放置在瓷砖中、遮挡裁剪、所有瓷砖都被渲染等操作完成后,为整个帧提供时间。https://imgtec.com/blog/a-look-at-the-powervr-graphics-architecture-tile-based-rendering/ - gman
@gman 是的。然而,我们正在谈论着色器基准测试。这种情况为我们提供了一个机会,让TBDR感到不舒服,从而获得相当充分的结果。我错了吗?从未测试过这个假设。 - Kirill Dmitrenko
但是你可以吗?我猜只要打开混合功能,你至少可以得到一些关于某个着色器是否比另一个更快的想法。关闭混合后,所有过度绘制都将被消除。你只需要记住,你获得的时间包括所有多边形分割、平铺桶处理等操作,因此这不仅仅是你的着色器执行时间。我想这也假设了扩展在平铺式架构上存在并且它实际返回了什么。 - gman
查看Apple文档,在iOS上目前不存在该扩展,所以我想这就回答了问题。 - gman
我已经在Android上相对成功地使用了PowerVR工具来检查GPU的整体占用情况(包括绘制调用时间等)。也许这些工具也可以在iOS上使用。 - Kirill Dmitrenko

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