代码之家  ›  专栏  ›  技术社区  ›  Justin Meiners

关于内联性能的问题

  •  2
  • Justin Meiners  · 技术社区  · 14 年前

    在C和C++中使用内联函数时,我遇到了一些问题。我被告知要在我经常使用的小函数上使用它,但我想确切地了解它是如何工作的。这里只是一个例子的一小部分。

    static inline point3D createPoint3D(float x, float y, float z){
       point3D newPosition;
       newPosition.x = x;
       newPosition.y = y;
       newPosition.z = z;
       return newPosition;
    }
    
    1. 它到底做什么?为什么它能帮助代码更快地运行?这是90年代的过时优化吗?

    2. 在大量函数上使用它是否不好?

    4 回复  |  直到 9 年前
        1
  •  5
  •   Jerry Coffin    14 年前
    1. 它应该做的是消除调用函数的开销。这对于像小函数这样几乎什么都不做的事情来说是非常重要的。事实上,这些都是非常常见的,即使在C++中实现了中途的正常性能,几乎也要求编译器自动地或多或少地自动扩展函数。

    2. 一般来说,使用它是毫无意义的。

    需要注意的两件事:1)大多数编译器可以/将在没有 inline 大多数编译器可以/将忽略 内联 关键字,如果他们认为函数不适合内联扩展(不过,只是FWIW,微软有一个 __forceinline 克服后者如果你 当然你比编译器更清楚)。

        2
  •  4
  •   t0mm13b    14 年前

    请参阅C++常见问题解答中的详细信息 here

    当编译器内联扩展函数调用时,函数的代码 插入到调用方的代码中 与#define宏一起发生)。这个 改善绩效,因为 优化器可以按程序运行 将调用的代码插入调用者。

    第9.3节

    内联函数可能会加快速度: 说明,可能会使事情

    内联函数可能会降低速度: 太多的内联可能会导致代码错误 按需分页虚拟内存 系统。换句话说,如果 可能大部分时间都在外面 代码。

    内联函数可能会使其更大: 这就是代码膨胀的概念 系统每个有100个内联函数 其中扩展到100字节 可执行代码,并在100中调用 地方,增加了1MB。是 我知道,但有可能 最后1MB可能导致系统 趴下。

    内联函数可能会 较小:编译器通常生成 更多要推送/弹出的代码 寄存器/参数 内联扩展函数体。 能够删除大量冗余代码 当优化器能够 大功能小。

    内联函数可能导致 颠簸:内联可能会增加 二进制可执行文件的大小,以及 那可能会引起打斗。

    内联函数可能会阻止 颠簸:工作集大小 (需要输入的页数) 记忆立刻)可能会下降,即使 可执行文件的大小增加。当f() 调用g(),代码通常在两个 不同的页面;当编译器 程序上集成了 g()转换为f(),代码经常在

    缓存未命中数:内联可能 使内环跨越 多行内存缓存, 这可能会导致

    内联函数可能会降低 缓存未命中数:内联 在二进制代码中 需要存储内部 循环。这最终可能导致 CPU限制的应用程序运行更快。

    内联函数可能无关紧要 CPU受限。大多数系统都是I/O绑定的, 数据库绑定或网络绑定, 意味着系统运行的瓶颈 总体性能取决于文件 系统、数据库或网络。 除非你的“CPU表”是在 让你的系统更快。(即使在 CPU受限的系统,内联将有帮助 仅在瓶颈内使用时 而瓶颈是 通常只有很小的百分比

    没有简单的答案:你有 玩它看看什么是最好的。 不要满足于简单的答案 比如,“从不使用内联函数”或者 内联函数当且仅当 函数小于N行 “这些一刀切的规则 将产生次优结果。

        3
  •  3
  •   pmg    14 年前

    别担心。 在你测量之前都是一样的。 而且,一旦您进行了度量,您就不会注意到使用ot编译的版本与不使用ot编译的版本之间的巨大差异 inline

    内联 是一个 直接将函数“内联”到编译器的代码流中,而不是“调用”它。这样就不需要设置堆栈,也不需要执行调用函数所需的其他杂务

            NOT INLINE                    INLINE
            ...                           ...
            code                          code
            call fx    -\                 code from fx
            code        |                 code from fx
            call fx   --|                 code from fx
            ...         |                 code
                        |                 code from fx
            code <------/                 code from fx
            ...                           code from fx
            return                        ...
    

    2) 你想用哪儿就用哪儿。编译器很可能会忽略你的建议

    3) 同2)

    4) 测量。实验与比较

        4
  •  2
  •   RBerteig Keith Adler    14 年前

    inline 关键字表示您认为此函数是一个很好的替代函数调用的候选者。它最好用于较小的函数,因为每次使用它都会在使用点放置一个新的函数体副本。过度使用会大大增加调用代码的大小。

    在经典C中,获得这种效果的唯一方法是使用宏,但宏有一个明显的缺点,即它们是纯文本替换,因此每次出现在替换文本中时都会对它们的每个参数进行求值。如何安全地允许宏具有局部变量也是不明显的。

    内联 .

    一个好的优化器将自行决定何时实际内联使用函数以及何时正常调用函数,因此,将函数随意标记为 内联