如何检查内联是否发生

how to check that inlining occurred

本文关键字:是否 何检查 检查      更新时间:2023-10-16

我想在我的项目中大量使用inline来提高性能。

据我所知,编译器可能是否应用内联;这取决于编译器。

不清楚我能做些什么来实现这一目标,但在朝这个方向前进之前,您是否知道一种方法来检查输出二进制文件中是否确实发生了内联?

使用 gcc -Winline 在内联函数未内联时获取警告。

使用 __attribute__ ((always_inline)) 强制内联函数。

话虽如此,请注意,如果您不明智地使用内联,您可能会破坏性能、编译时间并获得巨大的代码膨胀。

如果您使用的是 MS 编译器,则可能需要启用警告 C4710 以获取未内联函数的警告。

使用 gcc -S 选项生成汇编程序输出,然后在您喜欢的文本编辑器中检查输出。

但是,编译器通常比您更能判断内联何时实际提高性能。不要太急于强迫它;分析您的代码,看看内联是否真的更快。

编译器可能比你更聪明,但忽略这一点,假设你没有启用任何特殊的编译器标志,你可以转储名称列表并查找函数是否已生成。

static int foo(int x)
{
  return(x*x);
}
main()
{
  int x=1;
  foo(x);
}

要测试

not seth> gcc -o /tmp/foo /tmp/main1.c
not seth> nm /tmp/foo | grep foo
00000000004004c4 t foo
not seth> gcc -O -o /tmp/foo /tmp/main1.c
not seth> nm /tmp/foo | grep foo

inline关键字实际上与优化关系不大。大多数编译器将内联函数调用(函数本身可能必须单独编译,例如,如果您将其地址放在其他地方),无论 inline 关键字是否存在。

事实上,即使一个被调用的函数位于另一个转换单元中,一个聪明的链接器也可以在链接时内联它(MSVC 提供此功能作为"链接时间代码生成")。不过,它需要编译器和链接器之间的强力合作。

inline关键字存在的理由是允许 [非模板] 函数打破一个定义规则,从而在头文件中定义。函数的实际内联将由编译器根据传递给它的各种启发式和优化标志来决定,而不是基于 inline 关键字。

因此,大量使用inline可能对性能完全无济于事。如果您担心性能,请使用探查器来确定程序花费时间的位置(通常是您不希望花费的时间),并通过优化实际瓶颈来采取相应的措施。