简而言之,海湾合作委员会选项 -fipa-pta 有什么作用?
What, in short words, does the GCC option -fipa-pta do?
根据GCC手册,-fipa-pta
优化确实:
-fipa-pta
:执行过程间指针分析以及过程间修改和引用分析。此选项可能会导致过度 大型编译单元上的内存和编译时使用情况。它不是 默认情况下在任何优化级别启用。
我假设 GCC 试图根据过程中使用的指针和引用来区分可变和不可变的数据。具有更深入的海湾合作委员会知识的人可以解释-fipa-pta
做什么吗?
我认为"过程间"这个词是这里的关键。
我对 gcc 的优化器不是很熟悉,但我以前曾致力于优化编译器。以下有些推测;用一小粒盐服用,或与了解GCC内部结构的人确认。
优化编译器通常仅在每个单独的函数(或子例程或过程,取决于语言)中执行分析和优化。例如,给定如下代码人为示例:
double *ptr = ...;
void foo(void) {
...
*ptr = 123.456;
some_other_function();
printf("*ptr = %fn", *ptr);
}
优化程序将无法确定*ptr
的值是否已通过调用some_other_function()
而更改。
如果启用了过程间分析,那么优化器可以分析some_other_function()
的行为,并且它也许能够证明它不能修改*ptr
。给定这样的分析,它可以确定表达式*ptr
仍然必须计算123.456
,原则上它甚至可以用puts("ptr = 123.456");
替换printf
调用。
(事实上,使用类似于上述代码片段的小程序,我得到了相同的生成代码,带有-O3
和-O3 -fipa-pta
,所以我可能错过了一些东西。
由于典型的程序包含大量函数,以及大量可能的调用序列,因此这种分析可能非常昂贵。
如本文所引:
"-fipa-pta"优化在进行分析时会考虑被调用函数的主体,因此编译
void __attribute__((noinline))
bar(int *x, int *y)
{
*x = *y;
}
int foo(void)
{
int a, b = 5;
bar(&a, &b);
return b + 10;
}
使用 -FIPA-PTA 使编译器看到 bar 不修改 b,编译器通过将 b+10 更改为 15 来优化 foo
。int foo(void)
{
int a, b = 5;
bar(&a, &b);
return 15;
}
一个更相关的例子是"整数除法很慢"博客文章中的"慢"代码
std::random_device entropySource;
std::mt19937 randGenerator(entropySource());
std::uniform_int_distribution<int> theIntDist(0, 99);
for (int i = 0; i < 1000000000; i++) {
volatile auto r = theIntDist(randGenerator);
}
使用 -fipa-pta 编译它会使编译器看到 theIntDist 在循环中没有被修改,因此内联代码可以以与"快速"版本相同的方式常量折叠 - 结果是它的运行速度提高了四倍。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- ifstream什么都没读
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 我应该使用什么来代替void作为变体中的替代类型之一
- 简而言之,海湾合作委员会选项 -fipa-pta 有什么作用?