3

我正在和朋友讨论一个优化问题,需要一些帮助来追踪这个问题的答案,希望我可以进一步阅读一些官方文档。

有人告诉我,在生产构建设置中编译一个简单程序(即:CCOPTS+=-O4,无调试等)时,以下代码:

#define COEFFICIENT_F  (5.0f)
...
...
float f = 1.0f / COEFFICIENT_F;

...将自动优化为如下所示:

#define COEFFICIENT_F  (5.0f)
...
...
#define INV_COEFFICIENT_F (0.2f)
float f = 1.0f * INV_COEFFICIENT_F;

同时,如果我正在为调试构建进行编译(即:)CCOPTS+=-O0 DEBUG=-g,则代码不会在预处理器级别优化此类操作。

所以,我的问题是双重的:

  1. 传递给编译器的优化级别会影响预处理器做出的决定吗?
  2. 例如,GCC 是否会自动执行此类转换,包括在预处理时预先计算逆系数,并将其存储在我的代码的数据段中,以及乘以而不是除以倒数?

谢谢!

4

2 回答 2

4

你的答案是:

  1. 不会。预处理按照标准中的定义执行,不受任何优化级别的影响。

  2. 您所指的优化不是在预处理时执行的,而是在从前端到代码生成器的漫长道路上执行的。

于 2013-06-05T16:24:49.837 回答
1

这实际上取决于编译器的确切用法和确切情况。在您给出的确切示例中,编译器必须非常愚蠢才能弄清楚这一点1.0f/5.0f = 0.2f,就像1.0f*0.2f = 0.2f(好吧,在这两种情况下,结果可能0.1999996或类似的东西。

现在,如果相反,我们有一些编译器在编译过程中无法计算出的数据:

 float f[] = { 3.1415926f, 1.0f, 9.82f, 1.4142f };
 float res[4]; 

 for(int i = 0; i < 4; i++)
    res[i] = f[i] / COEFFICIENT_F;

对比

 for(int i = 0; i < 4; i++)
    res[i] = f[i] * INV_COEFFICIENT_F;

它可能会产生一些差异(特别是在较低的优化级别,因为优化器不会用其他数学运算替换琐碎的数学运算,直到您至少达到 -O2)。

这有多大的不同取决于处理器架构。

要找出确切的差异,您必须编写一个小程序并测量它。(做比四个更大的数字!)

于 2013-06-05T16:29:02.913 回答