双倍乘法与加法速度比较。

5

背景

我是一名航空航天工程和电子工程与计算机科学(EECS)专业的学生。目前我的工作需要处理大量的数学和物理问题,但还没有涉及到算法或汇编语言。

我设计和编写了各种各样的程序,从商业提案软件到卫星硬件控制器。

这项工作的大部分内容涉及在其他媒介中进行数学运算,然后编写代码来实现它。

在将这些方程放入代码之前,我会对其进行代数简化。但在花费时间进行此操作之前,我想知道是否应更青睐于加法操作还是乘法操作。(我已经知道除法成本更高。)


例子

B sub-x prime

这是我从其他工作中推导出来的一个方程,这基本上是我看到的典型情况。我们可以清楚地看到,有至少几种简化这个方程的方法。由于简化是由我自行决定的,所以我想选择有利于性能的选项,尽可能实用。我不会为了算法设计时间而追求最先进的性能。

问题

一般情况下,加法和乘法哪个操作更快?

我知道确定哪个更快的唯一方法是编写并运行基准测试,但这不是重点。 在我需要简化方程式时每次编写测试代码都不够重要。 我需要一个经验法则来应用于我的代数运算。

如果差异非常微小以至于接近可以忽略或无法确定,那么这是可以接受的答案,只要我知道它几乎没有任何影响。


支持研究

我知道在C和C++中,优化器会处理代数运算, 所以这是无问题的。然而,据我所知,Java编译器不会进行代数简化/优化。具体来说,这个答案表明这种情况存在,并且程序员应该进行这种优化。

这个问题的答案在互联网上分散,但我找不到一个确定的答案。前马里兰大学物理学生对Java进行了测试,但双倍性能数据缺失在表格中,而图形比例使结果难以辨认。魁北克大学计算机科学教授的测试仅显示整数操作的结果。这个SO答案解释说,在硬件层面上,乘法是一种更复杂的操作,但我也知道工程师们会考虑这些事情来设计处理器。
其他略微有用的链接:

9
编译器不进行优化,而是运行时进行优化。实际上,如果它不重要到需要编写基准测试,那么也就不重要到无论哪种方式都没关系了。话虽如此:加法通常会更快。 - Louis Wasserman
3
你应该更注重每个项的数量级,而不是是否可以最小化乘法次数,并以最小化溢出/下溢可能性的方式分组操作。话虽如此,在你的例子中实际上只有一个重构可能会有用:有2个项乘以(c-1)x。 - FredK
3
我的经验法则是尽可能使代码易读,因为正确性比速度更重要。在任何语言中,我很少遇到必须扭曲代数表达式以达到性能目标的情况。我的建议是用你最熟悉且一年后仍然容易阅读的方式编写表达式。如果有必要关注性能,那么你应该进行代码分析和实验。但你现在做的就是过早地优化。 - Jim Mischel
2
最好加入指令的混合,至少在现代英特尔处理器上是很重要的。请参见https://dev59.com/dXM_5IYBdhLWcg3w9oaG进行简要讨论。还请注意第二个答案中提供的Intel优化手册链接。而且,请记住处理器本身可以重新排序指令。随着新芯片设计的变化,具体情况也会发生改变。你将会花费大量时间,可能只能实现微小的性能提升。 - Jim Mischel
2
顺便提一下:始终记住,算术等价表达式可能具有非常不同的数值稳定性。当然,这取决于应用程序,但优化正确性(减少误差传播)可能比性能更重要。 - Hulk
显示剩余12条评论
1个回答

2
一般来说,应该编写最清晰的代码。JIT(而不是javac)采用简单、常见的模式并对其进行优化。这意味着使用简单、常见的模式通常是优化代码的最佳方式。
如果您对应用程序进行分析并发现代码未能以最佳方式运行,则可以尝试自己优化代码;
  • 有意义的微基准测试很难编写。
  • 结果可能对环境非常敏感。更改Java的更新或CPU型号可能会产生冲突的结果。
  • 当您对整个代码进行性能测试时,您可能会发现延迟不在您预期的时间点出现。例如,它们通常在IO中。
除非您确信优化真正有帮助,否则应坚持使用最简单、最易于维护的代码,并且您可能会发现它足够快速运行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接