gpt4 book ai didi

c - 为什么编译器不优化这个初始化?

转载 作者:太空狗 更新时间:2023-10-29 16:55:20 24 4
gpt4 key购买 nike

考虑以下 C 代码:

extern void foo(int* ip);

void myfunc(void)
{
int arr[15] = {0};
for (int i=0; i<10; i++)
{
arr[i] = 42;
}

foo(arr);
}

我尝试使用 gcc 和 clang,以及 -O3-Os。在所有情况下,编译后的程序集都会写入所有 15 个零,然后用 42 个覆盖其中的 10 个。

我想这可能只是因为还没有为这种情况编写优化,但对我来说这似乎是一个相当明显和常见的情况。是否存在阻碍优化的因素?

我在 x86-32 Linux 上使用了这些命令:

gcc -std=c99 -S -O3 hello.c
clang -std=c99 -S -O3 hello.c

最佳答案

这不是一个非常科学的解释,而只是一种直觉(不过,我确实碰巧知道一些 GCC 的内部结构)。

为了可靠地进行您想要的优化,编译器必须管理子数组切片。然后它变得非常复杂且容易出错。优化这么多的编译器可能会消耗大量内存(用于子数组的符号表示)和大量编译时间。这通常不值得付出努力(最好在编译器内部花费这些精力来优化循环)。

顺便说一句,GCC 有一个插件框架和 MELT扩展(MELT 是一种用于扩展 GCC 的 lispy 域特定语言,我是 MELT 的主要作者)。因此,您可以尝试添加一个新的优化 channel (通过 MELT 扩展或某些 C++ 插件)来完成这项工作。您很快就会意识到,您的传递要么非常具体,要么需要处理大量的 GCC 内部表示,并且很可能会耗尽编译时间和内存而收效甚微。

请注意,GCC 和 Clang 都巧妙地展开了两个循环(这在性能方面非常重要)。

顺便说一句,Frama-C (由同事开发的用于 C 程序的静态分析器)值分析器似乎能够推断出有关您的 arr

的良好属性

因此,请随意将优化添加到 GCC。如果您不知道(或没有时间 - 数月或数年)如何添加它,请随时向能够根据您的需要增强 GCC 的公司或组织付费。这可能是一百万欧元(或美元)/3 年的项目才能使该优化在有趣的案例上发挥作用。

如果您真的要花这么多钱,请通过电子邮件与我联系。

具有这种优化的编译器需要一些试探法来禁用它们(例如,如果 arr 是一个百万成员数组,并且您正在编写一些 sieve of Erasthothenes ,它可能不值得编译器努力在编译时保持复合索引的所有子片的并集)。

顺便说一句,您会接受一个慢 20 倍的优化编译器(在编译时更慢)以获得 yield (在运行时可能只有百分之几),这在实践中很少发生并且不是很重要吗?最后,我认为这不是优化的常见情况。 YMMV.

您可能对源到源转换器感兴趣,例如 PIPS4U

关于c - 为什么编译器不优化这个初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28992690/

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