sgemv
(或dgemv
)的
0.5 / (1+c)
,其中 c
是常数。
我想知道这些操作的复杂对应部分
zgemv
是否具有与纯实数相同的算术强度?
我的想法如下:
(a+b*i) * (c+d*i)
类型的复数乘法,其中i^2=-1
等于(ac - cd) + i*(bc + ad)
,因此有 4 次乘法和 2 次加法,总共 6 次操作。相反,要将两个纯实数相乘,只需要一次乘法。
要加载复数,必须加载两个双精度数,因此这也会使内存流量增加 2。
总共算力强度要大3倍左右?
非常感谢!
gemv 是矩阵向量乘积,因此结果的每个元素都是向量与矩阵的行或列的点积。这是乘法 和加法 ,而不仅仅是乘法。
在现代硬件上,这是通过一个 FMA 完成的,成本与一次乘法大致相同,免费获得加法。
优化的 ZGEMV 还会使用一些 FMA 进行复杂的乘法和加法,例如 2 个乘法,2 个 FMA 仅用于复杂的乘法。
或者如果添加到现有的实部和虚部累加器,则需要四个 FMA。 (创建两个长依赖链,因此您需要 展开更多内容来隐藏它,尽管您已经在添加到实部和虚部的 FMA 之间实现了指令级并行性。)
这是假设复数存储在实部和虚部的单独数组中,因此 SIMD 加载可以获得
[r0, r1, r2, r3]
和 [i0, i1, i2, i3]
的向量,保持问题纯粹垂直,而不需要像使用 [r0,i0, r1,i1, ...]
那样进行洗牌
交错布局(结构数组,又名 AoS)。如果您需要洗牌,那么计算强度会更高,但这不是“有用”的工作,而且它可能位于与可以运行 FMA 的执行单元不同的执行单元上。