这个问题适用于 Haswell 上带有 XMM/YMM 寄存器的打包、单精度浮点运算。
所以根据awesome, awesome table http://www.agner.org/optimize/instruction_tables.pdf由 Agner Fog 汇总,我知道 MUL 可以在端口 p0 和 p1 上完成(recp 吞吐量为 0.5),而 ADD 仅在端口 p1 上完成(recp 吞吐量为 1)。我可以排除这个限制,但我也知道 FMA 可以在端口 p0 或 p1 上完成(recp 吞吐量为 0.5)。因此,当 FMA 可以使用 p0 或 p1 并且它同时执行 ADD 和 MUL 时,为什么普通 ADD 仅限于 p1,这让我感到困惑。难道是我对表的理解有误?或者有人可以解释为什么会这样?
也就是说,如果我的阅读是正确的,那么英特尔为什么不直接使用 FMA 操作作为普通 MUL 和普通 ADD 的基础,从而提高 ADD 和 MUL 的吞吐量。或者,什么会阻止我使用两个同时、独立的 FMA 操作来模拟两个同时、独立的 ADD 操作?执行 ADD-by-FMA 会受到哪些处罚?显然,使用了更多数量的寄存器(2 个寄存器用于 ADD,3 个寄存器用于 ADD-by-FMA),但除此之外呢?
您并不是唯一一个对英特尔为何这样做感到困惑的人。阿格纳·雾在他的微架构 http://agner.org/optimize/microarchitecture.pdfHaswell 的手册写道:
奇怪的是,只有一个端口用于浮点加法,但有两个端口用于浮点乘法。
在阿格纳的留言板上他还写 http://agner.org/optimize/blog/read.php?i=285#352
浮点乘法和乘加融合有两个执行单元,但浮点加法只有一个执行单元。这种设计似乎不是最理想的,因为浮点代码通常包含比乘法更多的加法。
该线程继续提供有关该主题的更多信息,我建议您阅读这些信息,但我不会在这里引用。
他还在这个答案中讨论了这个问题sandy-bridge-and-haswell-sse2-avx-avx2 的每周期浮点数 https://stackoverflow.com/questions/15655835/flops-per-cycle-for-sandy-bridge-and-haswell-sse2-avx-avx2
Haswell 上 FMA 指令的延迟为 5,吞吐量为每个时钟 2。这意味着您必须保持 10 个并行操作才能获得最大吞吐量。例如,如果您想添加一个很长的 f.p 列表。数字,您必须将其分成十个部分并使用十个累加器寄存器。
这确实是可能的,但谁会为某个特定处理器进行如此奇怪的优化呢?
他的回答基本上回答了你的问题。您可以使用 FMA 使加法吞吐量加倍。事实上,我在加法吞吐量测试中这样做了,并且确实看到它翻倍了。
总之,此外,如果您的计算受延迟限制,则不要使用 FMA,而应使用 ADD。但如果吞吐量有限,您可以尝试使用 FMA(通过将乘数设置为 1.0),但您可能必须使用许多 AVX 寄存器来执行此操作。
我展开 10 次以获得最大吞吐量使用 ivy-bridge 和 haswell 进行循环展开以实现最大吞吐量 https://stackoverflow.com/questions/21090873/loop-unrolling-to-achieve-maximum-throughput-with-ivy-bridge-and-haswell/21600232#21600232
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)