代码之家  ›  专栏  ›  技术社区  ›  velenos14

zgemv与dgemv/sgemv的算术强度?

  •  0
  • velenos14  · 技术社区  · 1 年前

    这个 算术强度 属于 sgemv dgemv )在这组练习中派生( https://florian.world/wp-content/uploads/FM-High-Performance-Computing-I-Assignment-1.pdf )成为: 0.5 / (1+c) 哪里 c 是一个常数。

    我想知道 zgemv ,这些运算的复杂对应物,具有与纯实数运算相同的算术强度?

    我认为如下:

    类型的复数乘法 (a+b*i) * (c+d*i) 哪里 i^2=-1 ,等于 (ac - cd) + i*(bc + ad) ,所以有4次乘法和两次加法,总共有6次运算。相反,要将两个纯实数相乘,只需要进行一次乘法运算。

    要加载一个复数,必须加载两个双精度数字,因此这也会使内存流量增加2。

    总的来说,算术强度应该大约大3倍?

    非常感谢!

    1 回复  |  直到 1 年前
        1
  •  2
  •   Peter Cordes    1 年前

    gemv是矩阵的向量积,所以结果的每个元素都是向量和矩阵的一行或一列的点积 并添加 ,而不仅仅是相乘。

    在现代硬件上,这是用一个FMA(融合乘法-加法)完成的,成本与一个乘法差不多,有效地免费获得加法部分。

    优化的ZGEMV也会使用一些FMA进行复数乘法和加法,就像2次乘法一样,2个FMA只用于复数乘法。

    或者四个FMA,如果加上实部和虚部的现有累加器。(创建两个长依赖链,因此您需要 unroll more to hide it ,尽管添加到实部和虚部的FMA之间已经具有指令级并行性。)

    因此,对于FMA,它应该是计算强度的2倍左右:对于每个“元件”2倍的负载,FMA的数量是4倍。


    这是假设复数存储在实数和虚数的独立数组中,因此SIMD负载可以获得 [r0, r1, r2, r3] [i0, i1, i2, i3] ,保持问题完全垂直,不需要像使用 [r0,i0, r1,i1, ...] 交错布局(Array of Structs aka AoS)。如果你需要洗牌,那么计算强度会更高,但这不是“有用”的工作,而且它可能在不同的执行单元上,而不是可以运行FMA的执行单元。