简体   繁体   English

GNU C ++编译器((GCC)5.2.0)本身是否擅长“内联”?

[英]Is the GNU C++ compiler ((GCC) 5.2.0) good at “inlining” by itself?

I'm not asking why or when I should use inline in some code. 我不是问为什么或何时应该在某些代码中使用inline

I use inline where I think it's usual (like in get/set functions). 我在我认为很普通的地方使用inline (例如在get / set函数中)。 I read on stack some unusual example where inline sounds necessary. 我在堆栈上读了一些不常见的示例,这些示例需要inline声音。 I'm not sure that I'll recognize a such situation in my code... I mean, until I get an issue... 我不确定我是否会在代码中识别出这种情况...我的意思是,直到遇到问题为止...

So I wonder if for usual cases the compiler handles that as well as I do, maybe even better... 所以我想知道在通常情况下,编译器是否能像我一样处理该问题,甚至更好?

The reason why I would like to avoid inline , is to avoid having to implement in the headers ... About that a question pop in my mind: 我想避免使用inline的原因是避免必须在标头中实现...关于此问题,我脑海中浮现出一个问题:

is the compiler (I always consider the GCC compiler in my question) able to inline a function not implemented in the header ? 编译器(我一直认为我的问题是GCC编译器)是否可以inline标头中未实现的函数?

nb : I don't know if there is some internal changes about inline in C++14. nb:我不知道C ++ 14中的inline是否有一些内部更改。

First of all inlining something ie requiring inline substitution of the function body at the point of call doesn't mean that the implementation is constrained to do so : 首先,内联一些东西,即在调用时要求对函数体进行内联替换并不意味着实现必须受限制

7.1.2 Function specifiers 7.1.2功能说明符

2 A function declaration (8.3.5, 9.3, 11.3) with an inline specifier declares an inline function. 2具有内联说明符的函数声明(8.3.5、9.3、11.3)声明内联函数。 The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. 内联说明符向实现指示,在调用点处对函数体进行内联替换比通常的函数调用机制更可取。 An implementation is not required to perform this inline substitution at the point of call ; 在调用点不需要执行此内联替换的实现 however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected. 但是,即使省略此内联替换, 仍应遵守7.1.2定义的其他内联函数规则。

This alone should give a taste that it's a fuzzy heuristic to rely on compiler optimizations (or that it matters doing so) regarding this topic. 仅此一点就可以使人感到,依赖于此主题的编译器优化(或者这样做很重要)是一种模糊的启发式方法。 For example we know that the compiler has a hard time inlining function pointer calls but this is not of much importance. 例如,我们知道编译器很难内联函数指针调用,但这并不是很重要。

There are some examples of language constructs that the Standard mandates to be inlined and this not a matter of being a good compiler but a compliant one. 本标准要求内联一些语言构造的示例,这不是成为一个好的编译器而是一个合规的编译器。

Function Call operators of closure types 闭包类型的函数调用运算符

5.1.2 5.1.2

5 The closure type for a non-generic lambda-expression has a public inline function call operator (...) For a generic lambda, the closure type has a public inline function call operator member template (...) 5非泛型lambda表达式的闭包类型具有公共内联函数调用操作符(...)对于泛型lambda,闭包类型具有公共内联函数调用操作符成员模板(...)

constexpr functions constexpr函数

7.1.5 7.1.5

2 (...) constexpr functions and constexpr constructors are implicitly inline (7.1.2). 2(...)constexpr函数和constexpr构造函数隐式内联(7.1.2)。

Deleted functions 删除功能

8.4.3 8.4.3

A deleted function is implicitly inline. 删除的函数是隐式内联的。 [ Note: The one-definition rule (3.2) applies to deleted definitions. [注意:一定义规则(3.2)适用于已删除的定义。 — end note ] A deleted definition of a function shall be the first declaration of the function or, for an explicit specialization of a function template, the first declaration of that specialization. —尾注]删除的功能定义应为该功能的第一个声明,或者,对于功能模板的显式特化,应为该特化的第一个声明。

Other examples are member functions defined inside the class definition and a function defined in a friend declaration of a class. 其他示例是在类定义内定义的成员函数和在类的好友声明中定义的函数。 Inlining is not the best choice in every case (can increase program size) so for performance critical section I'd suggest benchmarking and deciding yourself; 内联并不是在每种情况下的最佳选择(可能会增加程序的大小),因此对于性能至关重要的部分,我建议进行基准测试并自行决定。 after all Do inline functions improve performance? 毕竟,内联函数是否可以提高性能?

The compiler can inline a function used in the same file (technically, "compilation unit") but not when compiling different files, since it doesn't have the source. 编译器可以内联在同一文件(技术上称为“编译单元”)中使用的函数,但是在编译不同文件时不能内联,因为它没有源代码。 That's why inline functions should be placed in the header file. 这就是将内联函数放置在头文件中的原因。

Without some kind of example code, it's VERY hard to say for sure what the compiler will do (even WITH code, it can be pretty darn difficult). 没有某种示例代码,很难确定编译器将执行什么操作(即使使用代码,也很难做到)。

Generally speaking, if the function is small, the compiler will inline functions that have their source code available during compilation (and others if you enable lto (link time optimisation). If you expect to be able to compile a function into an object file and get the function inlined, then you HAVE to use lto. 一般而言,如果函数较小,则编译器将内联具有在编译过程中可用的源代码的函数(如果启用了lto(链接时间优化),则将内联函数。如果希望能够将函数编译为目标文件,并且获取内联的函数,则必须使用lto。

A function that is large and static, called only once will also be inlined in most cases. 在大多数情况下,仅调用一次的大型静态函数也将内联。

The problem comes when you have several calls and the function is "more than tiny in size" - in other words more than 3-4 lines long. 当您有多个调用并且该函数“大小不只微小”时(换句话说,就是超过3-4行长),问题就来了。 Then the compiler has to balance between inlining and bloating the code, and not inlining and the cost of calls. 然后,编译器必须在内联和膨胀代码之间,而不是内联和调用成本之间取得平衡。 This is a very difficult balance to get right. 这是很难实现的平衡。 Profile-driven optimisation can help a lot here, but in general, the compiler will MOSTLY get it right, but not at all guaranteed - if in doubt (and it's important), use a benchmark of your application, and measure whether it gets better with a force inline attribute. 概要文件驱动的优化在这里可以提供很多帮助,但是总的来说,编译器将完全正确,但完全不能保证-如果有疑问(这很重要),请使用应用程序的基准测试并衡量它是否变得更好具有强制内联属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM