我一直在尝试重构一些中等大小的低级代码,并且我不能说我对编译器优化器内联代码的方式太满意了。
我不太了解gcc如何内联代码,但是对于我的一种特殊情况,通过使用以下选项,我得到的运行时速度相当于gcc 8.2.1中的手写代码:
-std=c++17 -Winline
-Ofast -march=native -DNDEBUG
-finline-limit=100000 --param large-function-insns=10000 --param large-stack-frame-growth=1000
--param inline-unit-growth=1000 --param early-inlining-insns=150 --param max-early-inliner-iterations=1000
-fopenmp -fPIC
没有内联选项,我的程序要慢3倍。我本来希望有一个更简单的选项来告诉编译器“相信我,当我说内联时,您必须内联它”。有这样的编译器选项吗?
注意:
现在我注意到一些奇怪的行为:
-fPIC
会使gcc发出-Winline
警告,说它没有内联。我不了解-fPIC
与内联之间的关系。--param early-inlining-insns=150
应该只用于优化编译时间,而不是gcc生成的代码。但是事实是,如果值是50
,我会得到 silent 不好的内联(gcc没有警告),如果值是1000
,我也会得到不好的内联( gcc这次警告我)。发生了什么事?__attribute__((always_inline))
,因为对于每个小功能都很难做到这一点,但是在我看来,即使具有此属性,gcc有时也不会内联该功能。 gcc是否真的总是使用此属性来内联函数?如何强制gcc内联我所有的inline
函数?我什至从概念上都无法理解,为什么手工制作看起来如此简单,但编译器却难以内联。内联是否存在可伸缩性优化问题?