- 从chat.so剪切 -
我在某个项目上使用gcc 4.6.2,并在使用英特尔VTune进行分析后 我注意到非常无意义的功能没有被内联(或者至少出现在热点下,我认为这意味着内联失败)
示例函数是重新解释强制转换,2个数字加法和三元语句
我相信这些都是在Windows中内联的,但是由于分析,认为它们不是在gcc 4.6.2下的linux中内联的。
我试图让一个ICC构建在linux上工作(在windows中工作),但这需要一点时间
直到那时,有人知道GCC 4.6.2在相对简单的编译器优化方面是否与VS2010不同?我在GCC中打开了-O3
导致我这样做的原因是这是对重要部分代码的重写,而在Windows上,性能大致相等或稍慢,而在Linux上它至少是2倍的速度。最丰富的答案将帮助我了解验证跨平台内联所需的步骤以及如何最好地处理这种情况,因为我了解这些情况非常具体情况。
编辑:另外,假设特定于业务的原因迫使我坚持使用GCC 4.6.2,如果不重写代码以使其不易维护,我该怎么办呢?
谢谢!
答案 0 :(得分:0)
首先,对于完整性来说非常明显:您是否完全确定所有执行可能非内联调用的文件是使用-O3
编译的?
gcc和VS编译器和工具链是完全不同的,如果他们的优化器表现得相当不同,它根本不会让我感到惊讶。
接下来让我观察三元运算符可能非常具有欺骗性。三元运算符几乎肯定会创建一个分支和潜在的构造函数调用,转换等。不要以为只是因为它是C ++中的简洁运算符,编译器才能为它生成少量代码。这可能会阻止编译器优化它。实际上,您可以尝试将三元代码重新编写为正常的if
语句,看看这是否有助于您的表现。
然后,一旦您开始进一步诊断,一个简单的尝试就是使用strings <binary> | grep function
并查看函数名是否显示在二进制文件中。如果它没有,那么它肯定是内联的(虽然它显示它可能是严格的调试信息而不是实际的代码)。还有其他工具,例如nm
,readelf
,elfdump
和dump
,它们也可以内省符号的二进制文件。您需要查看平台上可用的工具,然后尝试使用它们来查找相关功能。
另一个想法是将已编译的二进制文件加载到gdb中,并要求它dis
在文件和行处汇编代码,并在函数调用的位置进行。然后,您可以阅读反汇编代码以查看编译器的功能。大多数代码实际上应该是相当明显的。如果进行了实际的函数调用,您可能会看到类似call
指令的内容。