【问题标题】:How do I benchmark a WebGL shader?如何对 WebGL 着色器进行基准测试?
【发布时间】:2016-08-02 16:07:03
【问题描述】:

人们可以通过计算他在一秒钟内调用这些函数的次数来对常规 JavaScript 函数进行基准测试。但是,在 WebGL 上,gl.drawArrays 等函数是异步的,因此您无法通过对 API 调用进行基准测试来测量着色器所花费的时间。

有没有办法对 WebGL 函数进行基准测试?

【问题讨论】:

    标签: javascript webgl benchmarking


    【解决方案1】:

    对着色器进行基准测试非常困难,因为有大量上下文,而且它们非常特定于 GPU。

    您可以通过使用performance.now 在使用该着色器绘制一堆东西之前和之后判断一个着色器是否比另一个更快(几千到几百万个绘制调用),然后通过调用 gl.readPixels 停止 GPU .它会告诉你哪个更快。它不会告诉你它们有多快,因为停止 GPU 包括启动和停止时间。

    想想赛车。对于高速赛车,您需要时间加速到目的地。对于一辆赛车,你会计时一圈全速。你在计时前先让车跑一圈,你计时第二圈,汽车全速越过起跑线,终点线也全速。因此,您获得汽车的速度,而赛车则获得其加速度(通常与 GPU 无关,因为如果您追求速度,则永远不应该启动和停止它们)。

    另一种不添加开始/停止时间的计时方法是在requestAnimationFrame 帧之间绘制一堆。继续增加数量,直到帧之间的时间跳跃一整帧。然后比较着色器之间的数量。

    在实际使用中还有其他问题。例如,平铺的 GPU(如许多移动设备上的 PowerVR)试图剔除将被透支的部分图元。因此,在非平铺 GPU 上具有大量过度绘制的重型着色器在平铺 GPU 上可能会非常快。

    还要确保你的时机是正确的。如果您正在为顶点着色器计时,您可能希望使画布为 1x1 像素,并且片段着色器尽可能简单,并在一次绘制调用中传递大量顶点(以消除调用时间)。如果您正在为片段着色器计时,那么您可能需要一个大画布和一组包含多个完整画布四边形的顶点。

    另见WebGL/OpenGL: comparing the performance

    【讨论】:

      【解决方案2】:

      如果没有一些 GPU 供应商特定的工具,就无法获得准确的着色器执行时间。但是,除了 gman 的建议之外,还有 EXT_disjoint_timer_query 扩展,它允许测量绘制调用的执行时间,这又在很大程度上取决于着色器执行时间,尤其是当着色器非常重时(因此占用 GPU 花费的大部分时间执行你的绘图调用)。

      【讨论】:

      • EXT_disjoint_timer_query 不会为您提供有关 PowerVR (iOS) 等平铺架构的有用信息,因为它们使用延迟渲染器,他们能做的最好的事情就是在所有多边形之后为您提供整个帧的时间已经被分割,放入瓦片,遮挡剪裁,瓦片全部渲染等等。imgtec.com/blog/…
      • @gman 是的。但是,我们谈论的是 shader 基准测试。这种情况为 TBDR 提供了一个使生活不安的机会,从而获得了一些足够的结果。我在这里错了吗?从未测试过这个假设。
      • 但是你能吗?我想只要你打开混合,你至少可以知道一个着色器是否比另一个更快。随着混合,你所有的透支都会被剔除。你只需要记住你回来的时间包括所有的多边形分割、瓦片分桶等,所以它不仅仅是你的着色器的时间。我想这也假设扩展甚至存在于平铺架构上以及它实际返回的内容。
      • 检查 Apple docs 该扩展目前在 iOS 上不存在,所以我猜这回答了?
      • 我已经成功地将PowerVR tools 与 Android 一起使用来检查 GPU 的整体占用率(包括绘图调用时间等)。也许这些工具也可以与 iOS 一起使用。
      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 1970-01-01
      • 2015-09-15
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多