着色器中的点积与直接向量分量求和性能
Dot product vs Direct vector components sum performance in shaders
我正在为基于 Unity 的游戏编写用于高级光照计算的 CG 着色器。有时需要对所有向量分量求和。有两种方法:
- 写这样的东西:
浮点数 = v.x + v.y + v.z;
- 或者做类似的事情:
float sum = dot(v,float3(1,1,1));
我真的很好奇什么更快,代码风格看起来更好。
很明显,如果我们对 CPU 计算有相同的问题,第一种简单的方法要好得多。因为:
a) 不需要再分配一个float(1,1,1) vector
b) 不需要将每个原始向量 "v" 个分量乘以 1.
但由于我们是在 GPU 上运行的着色器代码中执行此操作,我相信点积函数有一些很棒的硬件优化,并且 float3(1,1,1) 的分配可能会转换为 no完全分配。
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));
}
cg 中点积的实现:https://developer.download.nvidia.com/cg/dot.html
恕我直言,差异是无法估量的,在 98% 的情况下,但第一个应该更快,因为乘法是一个“更昂贵”的操作
检查此 link。
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
第一次实施应该会更快。
我正在为基于 Unity 的游戏编写用于高级光照计算的 CG 着色器。有时需要对所有向量分量求和。有两种方法:
- 写这样的东西: 浮点数 = v.x + v.y + v.z;
- 或者做类似的事情: float sum = dot(v,float3(1,1,1));
我真的很好奇什么更快,代码风格看起来更好。
很明显,如果我们对 CPU 计算有相同的问题,第一种简单的方法要好得多。因为:
a) 不需要再分配一个float(1,1,1) vector
b) 不需要将每个原始向量 "v" 个分量乘以 1.
但由于我们是在 GPU 上运行的着色器代码中执行此操作,我相信点积函数有一些很棒的硬件优化,并且 float3(1,1,1) 的分配可能会转换为 no完全分配。
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));
}
cg 中点积的实现:https://developer.download.nvidia.com/cg/dot.html
恕我直言,差异是无法估量的,在 98% 的情况下,但第一个应该更快,因为乘法是一个“更昂贵”的操作
检查此 link。
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
第一次实施应该会更快。