【问题标题】:GLSL - Does a dot product really only cost one cycle?GLSL - 点积真的只需要一个周期吗?
【发布时间】:2012-05-25 23:06:15
【问题描述】:

我遇到过几种情况,声称在 GLSL 中进行点积运算最终会在一个循环中运行。例如:

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

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

我还在某处的 cmets 中看到过这样的声明:

    dot(value, vec4(.25))

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

    (x + y + z + w) / 4.0

再次声明 dot(vec4, vec4) 将在一个周期内运行。

我看到 ARB says that dot product (DP3 and DP4) and cross product (XPD 是单指令,但这是否意味着这些指令的计算成本与执行 vec4 加法一样昂贵?基本上有一些硬件实现,沿着类固醇的乘法累加线,在这里玩吗?我可以看到类似的东西在计算机图形学中是如何有用的,但是在一个周期内完成本身可能是相当多的指令听起来很多。

【问题讨论】:

    标签: glsl shader gpgpu


    【解决方案1】:

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

    一般来说,您不应假设点积是单循环的。

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

    我还在某处的 cmets 中看到过这样的声明:

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

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

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

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

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

    这里是否有一些硬件实现,类似于类固醇上的乘法累加?

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

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

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

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

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

    【讨论】:

    • 好的,谢谢。 “你不应该假设 ARB 汇编与实际的硬件机器指令代码有任何关系。”基本上是我希望的简洁答案。看起来 ARB 有点小众,很难找到很多谷歌可用的材料。这是我似乎无法验证的那些“部落知识”类型的事情之一,而且在一段时间内它是正确的事实是有道理的。很酷的东西。
    【解决方案2】:

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

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

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

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

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

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

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

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

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

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

    【讨论】:

    • 这是一个描述性措辞的答案,我非常感谢!
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-05
      • 2010-12-05
      • 2021-11-29
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多