11

在关于函数声明中的关键字的许多争论inline中,有人会指出它实际上会在某些情况下使您的程序变慢——如果我是正确的话,主要是由于代码爆炸。我自己在实践中从未遇到过这样的例子。什么是实际代码,其中使用inline可能会损害性能?

4

2 回答 2

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、splower 和 setsoftint。使内核更小更快。deraadt@好的

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

大约在同一时间,我开始寻求实际测量 OpenBSD 内核中的内联函数。我发现有一些性能提升很小,但大多数的可测量影响为 0,并且有几个使事情变得更慢并被杀死。至少还有一个 uninlining 产生了巨大的影响,其中一个是内部 malloc 宏(如果它的大小在编译时已知,这个想法是内联 malloc)和数据包缓冲区分配器,它们将内核缩小了 150kB 并具有显着的性能改进。

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

于 2014-06-27T13:38:25.083 回答
2

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

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

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

如果备份操作更广泛,在时间和机器周期方面,与函数调用机制相比,特别是如果函数被广泛调用,那么就会产生不利影响。

这似乎是操作系统中主要使用的一些特定功能的情况。

于 2015-08-21T21:19:32.477 回答