2

我正在处理一些在编译为 PIC(位置无关代码)时会变慢 70-80% 的代码,并正在寻找缓解问题的方法。问题的很大一部分是 gcc 坚持在每个函数中插入以下内容:

call __i686.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_,%ebx

即使这最终是函数内容的 20%。现在,ebx是一个调用保留寄存器,相关翻译单元(源文件)中的每个函数都在用GOT的地址加载它,很容易检测到这些static函数不能从翻译单元外部调用(它们的地址是从未采取)。那么为什么 gcc 不能ebx在大外部链接函数的开头加载一次,并生成静态链接函数,以便它们假设ebx已经加载了 GOT 的地址?是否有任何优化标志我可以用来强制 gcc 进行这种明显和大规模的优化,而不是将内联限制提高到天高,以便所有内容都内联到外部函数中?

4

2 回答 2

3

可能没有通用的解决方法,但您可以尝试使用内联选项。我猜static编译单元中的函数没有太多的调用者,所以代码复制的开销不会太糟糕。

使用 gcc 强制执行此类操作的最简单方法是设置attribute((always_inline)). 您可以使用依赖于 gcc 的宏来确保可移植性。

如果您不想修改代码(但static inline无论如何都会很好),您可以使用该-finline-limit选项对其进行微调。

于 2011-02-22T08:46:53.433 回答
1

不是真正的解决方案,但是:如果所讨论的函数不引用文件范围变量,您可以将它们全部放在一个翻译单元中,并在没有 -fPIC 标志的情况下编译它。然后像往常一样将它们与最终 SO 中的其他文件链接在一起。

于 2011-02-22T10:14:59.767 回答