我可以有选择地(强制)内联函数吗?

发布于 2024-11-30 06:36:46 字数 801 浏览 0 评论 0原文

清洁代码一书中(以及我遇到并阅读过的其他几本书) )建议保持函数较小,如果函数变大则将其分解。它还表明函数应该做一件事并且只做一件事。

Optimizing software in C++ 中,Agner Fog 表示,他不喜欢仅仅因为函数交叉就将其分解的规则一定的行数阈值。他指出,这会导致不必要的跳跃,从而降低性能。

首先,我明白,如果我正在处理的代码不是在一个紧密的循环中,并且这些函数很重,那么调用它们所花费的时间与函数中的代码所花费的时间相比就相形见绌了。执行。但是,假设我正在使用的函数在大多数情况下被其他对象/函数使用,并且正在执行相对琐碎的任务。这些函数遵循第一段中列出的建议(即执行一个单一函数并且很小/易于理解)。然后,我开始编写一个性能关键函数,该函数在紧密循环中利用这些其他函数,本质上是一个框架函数。最后,假设内联它们对性能关键功能有好处,但对任何其他功能没有任何好处(是的,我已经对此进行了分析,尽管我想避免大量复制和粘贴)。

立即,我们可以说标记函数inline并让编译器选择。但是,如果我不希望所有这些函数都位于 `.inl 文件中或在标头中公开,该怎么办?在我目前的情况下,性能关键函数和它使用的其他函数都在同一个源文件中。

总而言之,我是否可以有选择地(强制)内联单个函数的函数,以便最终代码的行为就像它是一个大函数,而不是对其他函数的多次调用。

In the book Clean Code (and a couple of others I have come across and read) it is suggested to keep the functions small and break them up if they become large. It also suggests that functions should do one thing and one thing only.

In Optimizing software in C++ Agner Fog states that he does not like the rule of breaking up a function just because it crosses a certain threshold of a number of lines. He states that this results in unnecessary jumps which degrade performance.

First off, I understand that it will not matter if the code I am working on is not in a tight loop and that the functions are heavy so that the time it takes to call them is dwarfed by the time the code in the function takes to execute. But let's assume that I am working with functions that are, most of the time, used by other objects/functions and are performing relatively trivial tasks. These functions follow the suggestions listed in the first paragraph (that is, perform one single function and are small/comprehensible). Then I start programming a performance critical function that utilizes these other functions in a tight loop and is essentially a frame function. Lastly, assume that in-lining them has a benefit for the performance critical function but no benefit whatsoever to any other function (yes, I have profiled this, albeit with a lot of copying and pasting which I want to avoid).

Immediately, one can say that tag the function inline and let the compiler choose. But what if I don't want all those functions to be in a `.inl file or exposed in the header? In my current situation, the performance critical functions and the other functions it uses are all in the same source file.

To sum it up, can I selectively (force) inline a function(s) for a single function so that the end code behaves like it is one big function instead of several calls to other functions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

新一帅帅 2024-12-07 06:36:46

没有什么可以阻止您将 内联 放入 .cpp 文件中的静态函数中。

一些编译器可以选择强制内联函数,请参阅 GCC __attribute__((always_inline)) 和大量选项来微调内联优化(请参阅 -minline-*参数)。

我的建议是在您认为合适的地方使用内联甚至更好的静态内联,并让编译器决定。他们通常做得很好。

There is nothing that prevents you to put inline in a static function in a .cpp file.

Some compilers have the option to force an inline function, see e.g. the GCC __attribute__((always_inline)) and a ton of options to fine tune the inlining optimizations (see -minline-* parameters).

My recommendation is to use inline or even better static inline wherever you see fit, and let the compiler decide. They usually do it pretty well.

零度° 2024-12-07 06:36:46

您不能强制内联。此外,与完成工作的成本相比,现代 CPU 上的函数调用相当便宜。如果您的函数足够大,需要分解,那么执行调用所需的额外时间基本上为零。

如果做不到这一点,您可以...尝试...使用宏。

You cannot force the inline. Also, function calls are pretty cheap on modern CPUs, compared to the cost of the work done. If your functions are large enough to need to be broken down, the additional time taken to do the call will be essentially nothing.

Failing that, you could ... try ... to use a macro.

世俗缘 2024-12-07 06:36:46

不,内联是对编译器的建议;它不会强迫它做任何事情。另外,如果您使用 MSVC++,请注意 __forceinline 也是用词不当;它只是比 inline 更强烈的推荐。

No, inline is a recommendation to the compiler ; it does not force it to do anything. Also, if you're working with MSVC++, note that __forceinline is a misnomer as well ; it's just a stronger recommendation than inline.

嘿咻 2024-12-07 06:36:46

这不仅是关于 C++ 的,也是关于老式直接 C 的。前几天我在思考这个问题,因为在嵌入式世界中,速度和空间都需要仔细管理,这确实很重要(而不是经常说的“别担心,你的编译器很聪明,并且内存在桌面/服务器开发中很普遍)。

我尚未审查的一种可能的解决方案是基本上对不同的变体使用两个名称,例如

inline int _max(int a, int b) {
    return a > b ? a : b;
}

然后

int max(int a, int b) {
    return _max(a, b);
}

这将赋予人们选择性的能力。调用 _max() 或max() ,但仍然定义了一次且仅一次的算法。

This is as much about good old fashioned straight C as it is about C++. I was pondering this the other day, because in an embedded world, where both speed and space need to be carefully managed, this can really matter (as opposed to the all too oft "don't worry about it, your compiler is smart and memory is cheap prevalent in desktop/server development).

A possible solution that I have yet to vet is to basically use two names for the different variants, something like

inline int _max(int a, int b) {
    return a > b ? a : b;
}

and then

int max(int a, int b) {
    return _max(a, b);
}

This would give one the ability to selectively call either _max() or max() and yet still having the algorithm defined once-and-only-once.

以酷 2024-12-07 06:36:46

如果您有一个已知的热门函数,并且希望编译器比平常更积极地内联,则 gcc/clang 提供的 flatten 属性可能值得研究。与 inline 关键字和属性相反,它适用于有关标记函数中调用的函数的内联决策。

__attribute__((flatten)) void hot_code() {
    // functions called here will be inlined if possible
}

请参阅 https://gcc.gnu.org/onlinedocs/gcc/Common- Function-Attributes.htmlhttps://clang.llvm.org/docs/AttributeReference.html#flatten 获取官方文档。

If you have a known-hot function an want the compiler inline more aggressively than usual the flatten attribute offered by gcc/clang might be something to look into. In contrast to the inline keyword and attributes it applies to inlining decisions regarding the functions called in the marked function.

__attribute__((flatten)) void hot_code() {
    // functions called here will be inlined if possible
}

See https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html and https://clang.llvm.org/docs/AttributeReference.html#flatten for official documentation.

无言温柔 2024-12-07 06:36:46

内联 - 例如,如果存在一个频繁调用函数 B 的函数 A,并且函数 B 相对较小,则配置文件引导优化会将函数 B 内联到函数 A 中。

VS 配置文件引导优化

您可以使用性能和诊断中心中的 Visual C++ 自动化配置文件引导优化插件来简化 Visual Studio 中的优化过程,也可以在 Visual Studio 中或在命令行上手动执行优化步骤。 我们推荐该插件,因为它更易于使用。有关如何获取该插件并使用它来优化您的应用的信息,请参阅配置文件引导优化插件

Inlining – For example, if there exists a function A that frequently calls function B, and function B is relatively small, then profile-guided optimizations will inline function B in function A.

VS Profile-Guided Optimizations

You can use the automated Profile Guided Optimization for Visual C++ plug-in in the Performance and Diagnostics Hub to simplify and streamline the optimization process within Visual Studio, or you can perform the optimization steps manually in Visual Studio or on the command line. We recommend the plug-in because it is easier to use. For information on how to get the plug-in and use it to optimize your app, see Profile Guided Optimization Plug-In.

茶底世界 2024-12-07 06:36:46

编译器实际上非常擅长生成优化代码。

我建议将代码组织成逻辑分组(如果可以增强可读性,则使用附加函数),如果合适的话将它们标记为内联,然后让编译器决定以最佳方式生成哪些代码。

Compilers are actually really really good at generating optimized code.

I would suggest just organizing your code into logical groupings (using additional functions if that enhanced readability), marking them inline if appropriate, and letting the compiler decide what code to optimally generate.

夜清冷一曲。 2024-12-07 06:36:46

令人惊讶的是,这一点还没有被提及,但到目前为止,您可以告诉编译器(我相信它可能只适用于 GCC/G++)强制内联函数并忽略与其相关的一些限制。

您可以通过 __attribute__((always_inline)) 来执行此操作。

使用示例:

inline __attribute__((always_inline)) int pleaseInlineThis() {
   return 5;
}

通常,您应该避免强制内联,因为编译器比您知道什么是最好的;然而,有几个用例,例如在操作系统/微控制器开发中,您需要内联调用,如果调用它,则会破坏功能。

C++ 编译器通常对受控环境不太友好,例如那些没有一些 hack 的环境。

Quite surprised this hasn't been mention yet but as of now you can tell the compiler (I believe it may only work with GCC/G++) to force inline a function and ignore a couple restrictions associated with it.

You can do so via __attribute__((always_inline)).

Example of it in use:

inline __attribute__((always_inline)) int pleaseInlineThis() {
   return 5;
}

Normally you should avoid forcing an inline as the compiler knows what's best better than you; however there are several use cases such as in OS/MicroController development where you need to inline calls where if it is instead called, would break the functionality.

C++ compilers usually aren't very friendly to controlled environments such as those without some hacks.

逆光飞翔i 2024-12-07 06:36:46

正如人们提到的,您应该避免这样做,因为编译器通常会做出更好的决定。您可以启用多种优化来提高性能。如果需要,这些将内联函数:

  • LTO:链接时优化或过程间优化
  • 配置文件引导优化:基于运行时配置文件的优化
  • BOLT:二进制优化和布局工具
  • Polly:高级循环和数据局部性优化器

As people mentioned, you should avoid doing that as the compiler usually makes better decisions. There are several optimizations that you can enable to improve performance. These will inline the functions if needed:

  • LTO: link-time optimization or interprocedural optimization
  • Profile guided optimization: optimizations based on a runtime profile
  • BOLT: Binary Optimization and Layout Tool
  • Polly: a high-level loop and data-locality optimizer
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文