着色器中的点积与直接向量分量总和性能

Cra*_*nog 6 performance shader cg hlsl

我正在编写 CG 着色器,用于基于 Unity 的游戏的高级光照计算。有时需要对所有向量分量求和。有两种方法可以做到这一点:

  1. 只需编写如下内容: float sum = vx + vy + vz;
  2. 或者做类似的事情: float sum = dot(v,float3(1,1,1));

我真的很好奇什么更快并且代码风格看起来更好。

显然,如果我们对CPU计算有同样的问题,第一种简单的方法要好得多。因为:

a) 不需要再分配一个float(1,1,1)向量

b) 无需将每个原始向量“v”分量乘以 1。

但由于我们在 GPU 上运行的着色器代码中执行此操作,因此我相信点积函数有一些很好的硬件优化,并且可能会在根本不分配的情况下转换 float3(1,1,1) 的分配。

float4 _someVector;

void surf (Input IN, inout SurfaceOutputStandard o){
   float sum = _someVector.x + _someVector.y + _someVector.z + _someVector.w;
    // VS
   float sum2 = dot(_someVector, float4(1,1,1,1));
}
Run Code Online (Sandbox Code Playgroud)

kef*_*ren 6

检查此链接

Vec3 Dot 的成本为 3 个周期,而 Scalar Add 的成本为 1。因此,在几乎所有平台(AMD 和 NVIDIA)中:

float sum = v.x + v.y + v.z;成本为 2 float sum = dot(v,float3(1,1,1));成本为 3

第一次实施应该更快。


Men*_*yus 5

在cg中实现Dot乘积: https: //developer.download.nvidia.com/cg/dot.html

恕我直言,在 98% 的情况下,差异是无法估量的,但第一个应该更快,因为乘法是一种“更昂贵”的操作