考虑下面的代码段示出了一些简单的算术运算gcc是否以代数方式优化C++代码,如果是的话,程度如何?
int result = 0;
result = c * (a + b) + d * (a + b) + e;
要获得的结果在CPU上方的表达将需要执行两个整数乘法和三个整数加法。但是,代数上面的表达式可以简化为下面的代码。
result = (c + d) * (a + b) + e
这两个表达式在代数上是相同的,但第二个表达式只包含一个乘法和三个加法。 gcc(或其他编译器)能够自己做出这种简单的优化。
现在假设编译器足够智能以进行此简单优化,是否能够优化更复杂的内容,如Trapezoidal rule(用于数值积分)。下面的示例近似sin(x)
下的区域,其中0 <= x <= pi
的步长为pi/4(为了简单起见,小)。请假定所有文字都是运行时变量。
#include <math.h>
// Please assume all literals are runtime variables. Have done it this way to
// simplify the code.
double integral = 0.5 * ((sin(0) + sin(M_PI/4) * (M_PI/4 - 0) + (sin(M_PI/4) +
sin(M_PI/2)) * (M_PI/2 - M_PI/4) + (sin(M_PI/2) + sin(3 * M_PI/4)) *
(3 * M_PI/4 - M_PI/2) + (sin(3 * M_PI/4) + sin(M_PI)) * (M_PI - 3 * M_PI/4));
现在上面的函数可以这样写,就像使用梯形法则一样简化了。这大大减少了获得相同答案所需的乘法/除法的次数。
integral = 0.5 * (1/no_steps /* 4 in th case above*/) *
(M_PI - 0 /* Upper and lower limit*/) * (sin(0) + 2 * (sin(M_PI/4) +
sin(3 * M_PI/4)) + sin(M_PI));
请提供指向C/C++语言规范的链接。在此之前,只有两种不同的**语言C和C++。选一个!你的问题对于SO来说太广泛了。请自己做一些研究。 gcc邮件列表可能是一个好的开始。或者你只是阅读源代码。 – Olaf
您可以随时编译并检查程序集以查看它的功能。 – NathanOliver
小心!当你开始考虑整数溢出时,这种代数重排通常会中断。我无法想到这个特定表达式的反例,但有很多表达式会打破它。 –