重复计算的性能

3 c++ optimization compiler-optimization

我想知道是否值得进行一次计算并存储结果,或者进行两次计算是否更快?

例如在本例中:

float n1 = a - b;
float n2 = a + b;
float result = n1 * n2 / (n1 * n2);
Run Code Online (Sandbox Code Playgroud)

最好这样做:

float result = (a - b) * (a + b) / ((a - b) * (a + b));
Run Code Online (Sandbox Code Playgroud)

?我知道通常我们存储结果,但我想知道做加法而不是调用内存来存储/检索值是否不是更快。

Joh*_*ann 6

这实际上取决于:对于像你这样的简单例子,这并不重要。编译器将生成相同的代码,因为它找到公共子表达式并消除重复的计算。

对于更复杂的示例,例如涉及函数调用,您最好使用第一个变体来“存储”中间结果。不必担心使用简单变量进行中间存储。这些通常都保存在CPU寄存器中,并且编译器在将值保存在寄存器方面非常擅长。

危险在于,对于更复杂的计算,编译器可能无法执行公共子表达式消除。例如,当您的代码包含充当编译器边界的函数调用时,就会出现这种情况。

另一个主题是,对于浮点,即使是像加法这样的简单运算也不是关联的,即 (a+b)+c 与 a+(b+c) 不同,因为最低位中存在伪影。这通常还会阻止公共子表达式消除,因为编译器不允许更改代码的语义。