GLSL - 点产品真的只花费一个周期吗?

ult*_*ous 9 shader gpgpu glsl

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

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

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

我在某处的评论中也看到了一个声明:

    dot(value, vec4(.25))
Run Code Online (Sandbox Code Playgroud)

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

    (x + y + z + w) / 4.0
Run Code Online (Sandbox Code Playgroud)

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

我看到ARB 说点产品(DP3和DP4)和交叉产品(XPD是单指令,但是这是否意味着那些与vec4添加一样计算成本昂贵?是否基本上有一些硬件实现,沿着在类固醇中多次积累,在这里发挥作用?我可以看到这样的东西在计算机图形学中是如何有用的,但是在一个循环中做一些可能是相当多的指令在他们自己听起来很多.

Nic*_*las 12

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

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

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

我在某处的评论中也看到了一个声明:

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

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

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

单指令,但这是否意味着那些与vec4添加一样计算成本高昂?

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

基本上是否有一些硬件实现,沿着类固醇上的多次累积,在这里发挥作用?

如果你想谈论硬件,它是非常特定于硬件的.曾几何时,有专门的网络产品硬件.这是在所谓的"DOT3凹凸贴图"和早期DX8时代的着色器时代.

但是,为了加快一般操作,他们不得不采取这种方式.所以现在,对于大多数现代硬件(也就是:任何Radeon HD级或NVIDIA 8xxx或更好的产品.所谓的DX10或11硬件),点式产品几乎就像他们所说的那样.每个乘法/加法占用一个周期.

但是,这个硬件也允许很多并行,所以你可以同时发生 4个独立的vec4点产品.每个人需要4个周期.但是,只要这些操作的结果不在其他操作中使用,它们就可以并行执行.因此,他们中的四个将需要4个周期.

再说一次,它非常复杂.和硬件有关.

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


dou*_*536 5

Nicol Bolas从"ARB组装"的角度处理了实际答案,或者研究了IR转储.我将解决这个问题"4倍数和3个加法在硬件中是一个循环?!这听起来不可能." .

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

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

通过完全流水线执行,指令可以分布到流水线的几个阶段.管道的所有阶段同时运行.

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

让我们研究一个4d点积,对于一个假设的核心,乘法延迟为3个周期,加上5个周期的延迟.

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

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

如果你需要做一个点产品而不得不等待答案,那么你将不得不等待结果的整个27周期延迟.但是,如果要计算1000个单独的点积,则需要1027个周期.前26个循环没有结果,在第27个循环中第一个结果出现结束,在第1000个输入发出后,最后一个结果又花了26个循环结束.这使得点积产生"一个周期".

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