webgl着色器调试/性能/成本

时间:2014-08-27 18:35:28

标签: glsl webgl shader

我一直在使用three.js来实验和学习GLSL和WebGL。我来自3d艺术世界所以我理解网格,3d数学,照明等的概念。虽然我参考了OpenGL和WebGL文献(以及gpu gems,eric lengyels数学书等),我似乎错过了一些关键适用于图形的CS概念。

目前我正在使用颜色进行调试,并与画布检查器一起查看绘制调用需要多长时间。

我感兴趣的是以下问题:

  1. GLSL的功能有多重。例如,在性能,MAD指令等方面,除法如何与乘法或sin相比较?
  2. 说你有类似的东西

    vec2 normalizedCoord = gl_FragCoord.xy / uniform_resolution.xy;
    vs
    vec2 normalizedCoord = gl_FragCoord.xy * uniform_resolution_inverse.xy;
    vs
    ... the same with lowp/mediump/highp
    

    精度/性能会发生什么变化?

  3. 或类似的东西

    vec4 someVec4 = ...;
    
    float sum = dot(someVec4,vec4(1.));
    vs 
    float sum = someVec4.x + someVec4.y + someVec4.z + someVec4.w;
    
  4. 纹理查找的含义是什么,例如,进行某种抽样 - SSAO或类似的东西?

  5. 这是可以在Michael Abrash Black book中找到的信息类型吗?

    如果有人可以帮助我更好地表达这个问题,我们将不胜感激:)

2 个答案:

答案 0 :(得分:4)

我确信没有经验的人可以给你一个更好的答案,但事实是。这取决于。

GPU是并行化的,它们都是不同的,因此在一个GPU上花费一定时间可能会花费更少的时间在另一个GPU上。

最重要的是,我不知道“画布检查员”是什么意思,但它可能无法显示事情花了多长时间,因为图形管道也是并行化的,多线程的,多进程的,所以,至少从JavaScript的POV中你可以知道提交命令需要多长时间,而不是执行它需要多长时间。例如,在Chrome中,命令将传递给GPU进程并继续JavaScript。然后GPU进程将其传递给GL / DirectX,然后再将命令传递给另一个进程,至少在大多数桌面操作系统上都是如此。

人们谈论使用gl.finish找出事情需要多长时间,但即使这样也行不通,因为它并没有告诉你GPU需要多长时间才能运行。它告诉你GPU运行多长时间+同步所有这些进程需要多长时间。当你唯一可以衡量的是汽车从停止状态到另一个停止状态时,这有点像问“汽车行驶的速度有多快”。你可以告诉一辆汽车在一定时间内从A点到B点,但你无法测量哪辆车达到了最快的速度。一辆车可能在1秒内从0到60,然后花了3秒钟减速。其他0-20瞬间,4秒到达目标然后立即停止。两辆车都花了4秒钟。如果所有你能测量的是他们花了4秒钟你就无法确定哪个命中了更快的速度。

更糟糕的是,你有像所有iOS设备和许多Android设备那样的平铺架构,直到他们拥有所有命令才能实际绘制。然后,他们生成命令的“图块”以呈现屏幕的不同部分。

好的,这不是主题。

通常,代码越少越快,纹理查找速度慢,GPU具有纹理缓存,因此在“典型”使用中,纹理缓存跨越多边形,纹理缓存有助于吨。您可以通过执行随机纹理查找来终止纹理缓存。例如,制作一个随机纹理,使用该纹理计算另一个纹理的纹理坐标。这将完全扼杀纹理缓存,GPU将运行得非常慢。

According to this调速很快。 Dot产品很快。乘法和加法很快。线性插值很快。

答案 1 :(得分:0)

如果您熟悉SIMD寄存器以及如何使用它们(例如:使用SSE内在函数或ASM),您很快就会注意到GPU寄存器与CPU的SIMD寄存器非常相似。 所有作业性能都与处理单元与其内存(CPU的主存储器或GPU的图形适配器RAM)之间的带宽相关联。在某些执行方案中,无论您使用何种处理单元,您甚至可以在剩余的自由寄存器中对处理费用(主要是阴影时的线性代数计算)进行除法和负载均衡。