在关于函数声明中inline
关键字的许多争论中,有人会指出它在某些情况下实际上会使程序变慢 - 主要是由于代码爆炸,如果我是正确的。我自己从未在实践中遇到过这样的例子。使用inline
可能会对性能产生不利影响的实际代码是什么?
答案 0 :(得分:20)
整整10年和前一天我在OpenBSD中做了这个提交:
http://www.openbsd.org/cgi-bin/cvsweb/src/sys/arch/amd64/include/intr.h.diff?r1=1.3;r2=1.4
提交消息是:
deinline splraise,spllower和setsoftint。 使内核更小更快。 deraadt @ ok
据我记得内核二进制缩小了超过100kB并且没有一个测试用例可以生成变得更慢并且几个宏基准测试(比如编译内核)明显更快(如果我没记错的话,可以达到5-10%) ,但不要引用我的话。
大约在同一时间我开始尝试在OpenBSD内核中实际测量内联函数。我找到了一些性能上升幅度最小的产品,但是大多数产品都有0次可衡量的影响,而且有些产品的速度慢得多,并且被杀死了。至少还有一个非内联产生了巨大的影响,其中一个是内部malloc宏(其中的想法是内联malloc,如果它在编译时具有已知的大小)和数据包缓冲区分配器,它将内核缩小了150kB并具有显着的性能改善。
有人可以推测,虽然我没有证据,但这是因为内核很大,我们在执行系统调用时仍然难以留在缓存中,而且每一点都有帮助。那么在这些情况下实际帮助的只是二进制文件的缩小,而不是执行的指令数量。
答案 1 :(得分:2)
想象一个没有参数的函数,但是具有一致数量的中间值或寄存器使用的密集计算。然后内联该函数在具有一致数量的中间值或注册用法的代码中。
没有参数使调用过程更加轻量级,因为不需要耗时的堆栈操作。
当内联时,编译器必须保存许多寄存器,并将其他寄存器溢出以用于新函数,以最坏的方式重现函数调用所需的寄存器和数据备份过程。
如果备份操作在时间和机器周期方面更加广泛,与函数调用机制相比,特别是如果广泛调用函数,则会产生不利影响。
这似乎是操作系统中主要使用的某些特定功能的情况。