我遇到过几种情况,声称在GLSL中做点积将最终在一个周期内运行。例如:
顶点和片段处理器在四个向量上运行,在一个周期内执行四组分指令,如加法,乘法,乘法累加或点积。
http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter35.html
我在某处的评论中也看到了一个声明:
dot(value, vec4(.25))
与以下相比,是一种更有效的平均四个值的方法:
(x + y + z + w) / 4.0
同样,声称点(vec4,vec4)将在一个周期内运行。
我看到ARB says that dot product (DP3 and DP4) and cross product (XPD是单指令,但这是否意味着那些与vec4添加一样计算成本高昂?基本上是否有一些硬件实现,沿着类固醇上的多次累积,在这里发挥作用?我可以看到这样的东西在计算机图形学中是如何有用的,但是在一个循环中做一些可能是很多说明就像他们自己听起来很多。
答案 0 :(得分:11)
这个问题无法以任何明确的方式作为一个整体来回答。硬件中的任何操作需要多长时间,不仅仅是硬件特定的,还有特定于代码的。也就是说,周围的代码可以完全掩盖操作所需的性能,或者可以使其花费更长的时间。
通常,您不应该假设点积是单周期的。
然而,某些方面肯定可以回答:
我在某处的评论中也看到了一个声明:
与以下相比,是一种更有效的平均四个值的方法:
我希望这有点真实,只要x
,y
,z
和w
实际上是不同的浮动值而不是成员相同的vec4
(也就是说,它们不是value.x
,value.y
等。如果它们是同一向量的元素,我会说任何体面的优化编译器都应该将这两者编译到同一组指令中。一个好的peephole optimizer应该抓住这样的模式。
我说这是“有点真实”,因为它取决于硬件。点积版本至少应该不是慢。同样,如果它们是同一向量的元素,优化器应该处理它。
单个指令,但这是否意味着那些与vec4添加一样计算成本高昂?
您不应该假设ARB程序集与实际硬件计算机指令代码具有任何关系。
基本上是否存在一些硬件实现,沿着类固醇上的多次累积,在这里发挥作用?
如果您想谈论硬件,它是非常特定于硬件的。曾几何时,有专门的网络产品硬件。这是在所谓的“DOT3凹凸贴图”和早期DX8时代的着色器时代。
然而,为了加快一般操作,他们不得不采取这种方式。所以现在,对于大多数现代硬件(也就是:任何Radeon HD级或NVIDIA 8xxx或更好的产品。所谓的DX10或11硬件),点式产品几乎就像他们所说的那样。每个乘法/加法都需要一个周期。
但是,此硬件还允许大量并行,因此您可以同时发生4个单独的vec4
点产品 。每个人需要4个周期。但是,只要这些操作的结果不在其他操作中使用,它们就可以并行执行。因此,他们中的四个将需要4个周期。
所以再次,它非常复杂。与硬件有关。
最好的办法是从合理的开始。然后了解您尝试编写的硬件,并从那里开始工作。
答案 1 :(得分:5)
Nicol Bolas从#AR; ARB汇编"的角度处理了实际的答案。或者看看IR转储。我将解决问题" 4个倍数和3个加法如何在硬件中成为一个周期?!这听起来不可能。" 。
使用繁重的流水线操作,无论多么复杂,都可以使任何指令具有一个周期的吞吐量。
不要将此与一个延迟周期混淆!
通过完全流水线执行,指令可以分散到流水线的几个阶段。管道的所有阶段都同时运行。
每个周期,第一阶段接受新指令,其输出进入下一阶段。每个循环,结果都出现在管道的末端。
让我们研究一个4d点积,对于一个假设的核心,乘法延迟为3个周期,加上5个周期的延迟。
如果这条管道以最差的方式布局,没有矢量并行性,那么它将是4次乘法和3次加法,总共有12 + 15个周期,总延迟为27个周期。
这是否意味着点积需要27个周期?绝对不是,因为它可以在每个周期开始一个新的,并在27个周期后得到它的答案。
如果你需要做一个点积并且不得不等待答案,那么你将不得不等待结果的整个27周期延迟。但是,如果要计算1000个单独的点积,则需要1027个周期。前26个循环没有结果,在第27个循环中第一个结果出现结束,在第1000个输入发出后,最后一个结果又花了26个循环结束。这使得点积产生了一个周期"。
真正的处理器以各种方式分配各个阶段的工作,提供更多或更少的流水线阶段,因此它们可能具有与我上面描述的完全不同的数字,但是这个想法保持不变。通常,每个阶段的工作量越少,时钟周期就越短。
答案 2 :(得分:0)
关键是vec4可以在一条指令中“操作”(参见Intel对16字节寄存器操作所做的工作,也就是IOS加速框架的基础)。
如果你开始分裂和混合矢量,那么矢量将不再是执行操作的矢量的“单个存储器地址”。