gpt4 book ai didi

c - 提前编译器如何确定优化要走多远?

转载 作者:行者123 更新时间:2023-12-03 17:23:22 28 4
gpt4 key购买 nike

现代编译器中的优化越来越好,通过基本优化(如常量折叠)来利用 SIMD 指令。然而,我想知道这些优化应该进行到什么程度,以及现在编译器是如何做出这个决定的。

让我们看一个例子:

#include <stdio.h>

static double naive_sin(double n) {
return n - n*n*n / 6.0 + n*n*n*n*n / 120.0 + n*n*n*n*n*n*n / 5040.0;
}

int main() {
printf("%f\n", naive_sin(1.0));

return 0;
}

使用 GCC 编译时使用 -O3 ,可以观察到得到的浮点数是由编译器计算出来的,并存储在源代码中。进一步优化显然是不可能的。

现在,让我们看第二个例子:
#include <stdio.h>

int main() {
double start = 0.0;

for (int i = 0; i < 100; i++) {
start += 1.0;
}

printf("%f\n", start);

return 0;
}

考虑到第一个示例的结果,我们可以期望编译器应用类似的优化并生成常量 100.0。在生成的机器代码中。但是,在查看输出时,结果发现循环仍然存在!

显然,这种优化并不总是可行的。假设您正在编写一个程序来计算 pi 到一百万位。这样的程序不需要用户输入,因此理论上可以通过编译器将结果硬编码到机器代码中。当然,这不是一个好主意,因为与仅运行优化程度较低的版本相比,编译器在内部评估这样的程序需要更长的时间。

在这种情况下,是什么让编译器决定不优化循环?是否有优化这种代码的语言/编译器,或者有什么可以防止这种情况?它可能与无法预测程序是否会结束的概念有关?

最佳答案

这实际上只是启用了哪些优化以及编译器中实际可用的优化的问题。一些优化,如函数内联和常量传播,基本上是普遍可用的并且相对容易实现。因此,大多数编译器将使用大多数优化设置来优化第一个程序。

第二个程序需要循环分析和循环消除来优化,这要复杂得多。编译器可能可以优化第二个程序,但您的编译器很可能没有优化此类循环的机制(证明浮点优化的正确性通常比证明整数优化的正确性要复杂得多)。请注意,如果 start,我的 GCC 版本确实优化了循环被声明为 int .

关于c - 提前编译器如何确定优化要走多远?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18027467/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com