11

我遇到过几种情况,声称在 GLSL 中做点积最终会在一个周期内运行。例如:

顶点和片段处理器在四个向量上运行,在单个周期内执行四分量指令,例如加法、乘法、乘法累加或点积。

http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter35.html

我还在某处的评论中看到了这样的说法:

    dot(value, vec4(.25))

与以下相比,将是平均四个值的更有效方法:

    (x + y + z + w) / 4.0

同样,声称 dot(vec4, vec4) 将在一个周期内运行。

我看到 ARB说点积(DP3 和 DP4)和叉积(XPD是单指令,但这是否意味着它们的计算成本与执行 vec4 加法一样?基本上有一些硬件实现,类似于类固醇上的乘法累加,在这里发挥作用?我可以看到类似的东西在计算机图形学中是如何有用的,但是在一个周期内完成可能是相当多的指令听起来很多。

4

3 回答 3

12

这个问题不能以任何明确的方式作为一个整体来回答。任何操作在硬件中需要多长时间不仅是特定于硬件的,而且是特定于代码的。也就是说,周围的代码可以完全掩盖操作所需的性能,或者它可以使其花费更长的时间。

通常,您不应假设点积是单周期的。

但是,有些方面肯定可以回答:

我还在某处的评论中看到了这样的说法:

与以下相比,将是平均四个值的更有效方法:

我希望这是真的,只要x, y, z, andw实际上是不同的浮点值而不是相同的成员vec4(也就是说,它们不是value.x,value.y等)。如果它们是同一向量的元素,我会说任何体面的优化编译器都应该将它们编译为同一组指令。一个好的窥视孔优化器应该能捕捉到这样的模式。

我说它“有点真实”,因为它取决于硬件。点积版本至少应该不会更慢。同样,如果它们是同一向量的元素,优化器应该处理它。

单条指令,但这是否意味着这些指令的计算成本与执行 vec4 加法一样昂贵?

您不应假设 ARB 程序集与实际的硬件机器指令代码有任何关系。

基本上有一些硬件实现,沿着类固醇的乘法累加线,在这里玩吗?

如果你想谈论硬件,它是非常特定于硬件的。曾几何时,有专门的点积硬件。这是在所谓的“DOT3 凹凸贴图”和早期 DX8 着色器时代的时代。

但是,为了加快一般的行动,他们不得不把那种东西拿出来。所以现在,对于大多数现代硬件(又名:任何 Radeon HD 级或 NVIDIA 8xxx 或更好的硬件。所谓的 DX10 或 11 硬件),点产品的功能与他们所说的差不多。每个乘法/加法占用一个周期。

但是,此硬件还允许大量并行性,因此您可以同时发生vec44 个独立的点积。每个需要 4 个周期。但是,只要这些操作的结果不被其他人使用,它们都可以并行执行。因此,它们四个总共需要 4 个周期。

再说一遍,这很复杂。并且依赖于硬件。

你最好的选择是从合理的开始。然后了解您尝试编写代码的硬件,并从那里开始工作。

于 2012-05-25T23:39:43.440 回答
5

Nicol Bolas 从“ARB 组装”或查看 IR 转储的角度处理了实际答案。我将解决这个问题“4 个倍数和 3 个加法怎么可能是一个硬件周期?!这听起来不可能。” .

使用繁重的流水线,无论多么复杂,都可以使任何指令具有一个周期的吞吐量。

不要将此与一个延迟周期混淆!

通过完全流水线执行,一条指令可以分散到流水线的多个阶段。管道的所有阶段同时运行。

每个周期,第一阶段接受一条新指令,其输出进入下一个阶段。每个循环,一个结果从管道的末端出来。

让我们检查一个 4d 点积,假设内核具有 3 个周期的乘法延迟和 5 个周期的相加延迟。

如果这条管道以最糟糕的方式布置,没有向量并行性,它将是 4 次乘法和 3 次加法,总共有 12+15 个周期,总延迟为 27 个周期。

这是否意味着一个点积需要 27 个周期?绝对不是,因为它可以在每个周期开始一个新的,并在 27 个周期后得到答案。

如果您需要做一个点积并且必须等待答案,那么您将不得不等待完整的 27 个周期延迟才能得到结果。但是,如果要计算 1000 个单独的点积,则需要 1027 个周期。前 26 个循环,没有结果,第 27 个循环第一个结果出来结束,第 1000 个输入发出后,又花了 26 个循环,最后一个结果出来结束。这使得点积采取“一个周期”。

真正的处理器以各种方式将工作分布在各个阶段,提供或多或少的流水线阶段,因此它们的数量可能与我上面描述的完全不同,但想法保持不变。通常,每个阶段所做的工作越少,时钟周期就越短。

于 2016-03-08T08:16:26.267 回答
0

关键是 vec4 可以在一条指令中“操作”(参见英特尔在 16 字节寄存器操作上所做的工作,也就是 IOS 加速框架的大部分基础)。

如果您开始拆分和拆分向量,则将不再有向量的“单个内存地址”来执行操作。

于 2012-09-15T18:15:04.497 回答