是否有一个内联对C程序的性能有害的实际例子?

是否有一个内联对C程序的性能有害的实际例子?,c,performance,optimization,inline-functions,C,Performance,Optimization,Inline Functions,在许多关于函数声明中的inline关键字的争论中,有人会指出,在某些情况下,它实际上会使程序变慢——如果我没有说错的话,主要是由于代码爆炸。我自己在实践中从未遇到过这样的例子。使用内联会对性能造成不利影响的实际代码是什么?整整10年前一天,我在OpenBSD中做了以下承诺: 提交消息是: 脱线SPLLISE、spllower和setsoftint。 使内核更小更快。 德拉德特@ok 据我记忆所及,内核二进制文件缩减了100kB以上,并且没有一个测试用例会变得更慢,而且几个宏基准测试(如编译内核

在许多关于函数声明中的
inline
关键字的争论中,有人会指出,在某些情况下,它实际上会使程序变慢——如果我没有说错的话,主要是由于代码爆炸。我自己在实践中从未遇到过这样的例子。使用
内联
会对性能造成不利影响的实际代码是什么?

整整10年前一天,我在OpenBSD中做了以下承诺:

提交消息是:

脱线SPLLISE、spllower和setsoftint。 使内核更小更快。 德拉德特@ok

据我记忆所及,内核二进制文件缩减了100kB以上,并且没有一个测试用例会变得更慢,而且几个宏基准测试(如编译内核)的速度明显更快(如果我没记错的话,为5-10%,但请不要引用我的话)

大约在同一时间,我开始寻求在OpenBSD内核中实际测量内联函数。我发现有几个性能提升很小,但大多数都没有可测量的影响,有几个使事情变得更慢,并被杀死。至少还有一个未内联产生了巨大的影响,那就是内部malloc宏(如果malloc的大小在编译时已知的话,可以内联malloc)和数据包缓冲区分配器,它们将内核缩减了150kB,并显著提高了性能


虽然我没有证据,但有人可以推测,这是因为内核很大,在执行系统调用时,我们很难留在缓存中,每一点都有帮助。因此,在这些情况下,真正有帮助的只是二进制文件的缩减,而不是执行的指令数。

想象一个没有参数的函数,但是具有一致数量的中间值或寄存器使用的密集计算。然后将该函数内联到具有一致数量的中间值或寄存器用法的代码中

没有参数会使调用过程更加轻量级,因为不需要耗时的堆栈操作

内联时,编译器必须保存许多寄存器,并溢出其他寄存器以用于新函数,以最糟糕的方式再现函数调用所需的寄存器和数据备份过程

与函数调用机制相比,如果备份操作在时间和机器周期方面更具扩展性,特别是在函数被广泛调用的情况下,则会产生不利影响


这似乎是操作系统中大量使用的某些特定函数的情况。

请注意,
inline
只是一个建议;编译器可以随意忽略它。如果许多编译单元都包含相同的大内联方法,并且只使用一次,那么您可能会有一个退化的示例。。。不过,这取决于不进行链接时代码生成或诸如此类的操作。正如@dan04所说,编译器不需要听您的,而且通常它非常智能。很多地方,例如max function('int max(int A,int b)')可以只是内联的(实际上也可以定义为宏,并具有相同的效果)。程序不会在内存中“跳转”到该函数,也不会在堆栈中加载变量。大量的使用。当然内联可能是有害的——如果不是,编译器(或开发人员)就会一直内联所有东西。它增加了寄存器压力和代码大小/L1i缓存占用,这两者都很容易成为比函数调用开销更大的性能问题。几年前,linux内核中也对删除内联进行了类似的更改。