中文
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助
鲲鹏小智

内联函数

原理

对于频繁调用的小函数,函数调用的时间开销可能已经远高于函数本身的时间开销。这时可以通过在函数的定义前面增加inline关键字,将函数定义为内联函数来降低函数调用的开销,提高程序性能。

内联函数是在编译阶段将函数体嵌入到调用该函数的语句中。GCC编译器中函数内联的相关属性如下表 GCC编译器中函数内联的相关属性所示。表格内容说明仅指定inline属性的函数不一定内联,编译器会根据程序使用的编译选项和优化等级,同时结合实际情况,比如函数体大小、函数体内是否有递归、是否为可变数目参数等来决定是否允许内联展开。

表1 GCC编译器中函数内联的相关属性

属性名

属性说明

inline

建议编译器内联,但不一定内联

always_inline

强制内联

noline

防止考虑为内联函数

GCC内联相关的编译选项及可以使能的优化级别如下表 GCC内联相关的编译选项及可以使能的优化级别所示。

表2 GCC内联相关的编译选项及可以使能的优化级别

编译选项

优化级别

说明

early-inlining

-O0,-O1,-O2,-O3,-Os

针对两类函数(标记为always_inline的函数和函数执行体比调用开销小的函数),在编译器执行内联分析前完成内联。

inline-functions-called-once

-O1,-O2,-O3,-Os

考虑所有被调用一次的静态函数,即使它们没有被标记为内联,也可以内联到它们的调用者中。如果集成了对给定函数的调用,则该函数本身不会作为汇编代码输出。

inline-small-functions

-O2, -O3, -Os

当函数体小于预期的函数调用代码时,将函数集成到它们的调用者中(因此程序的整体大小变小)。编译器试探性地决定哪些函数足够简单,值得以这种方式集成。此内联适用于所有函数,甚至那些未声明为内联的函数。

inline-functions

-O2, -O3, -Os

考虑所有用于内联的函数,即使它们没有被声明为内联。编译器试探性地决定哪些函数值得以这种方式集成。

如果对给定函数的所有调用都被集成,并且该函数被声明为静态,则该函数本身通常不会作为汇编代码输出。

详细介绍请参见GCC手册:

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

修改方式

修改前:

int func(int a, int b)
{
    return (a + b)*(a + b);
} 

修改后:

/*建议内联*/
static inline int func(int a, int b)
{
    return (a + b)*(a + b) ;
}

或者:

/*强制内联*/
static inline
__attribute__((always_inline)) int func(int a, int b) 
{
    return (a + b)*(a + b) ;
}