本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4975474.html


今天我在优化公司项目代码的过程中,借助了Intel的VTune工具查看热点函数,发现有一个名为GetMatrixKey的函数调用频率很高,这个函数的主要作用是从一个矩阵数组中获取Matrix,其中还包含了指针检查与数组越界检查。考虑到这个函数的功能很简单,我就把它的实现挪到了头文件,并加上了inline关键字。随后我查看了一下这个函数的调用,发现它只在下面这个函数中被引用了(其中XXXX是类的名字,可以忽略掉):

// Author : 大便一箩筐 http://www.cnblogs.com/dbylk
D3DXMATRIX* XXXX::GetTransform(int nFrame) {
return GetMatrixKey(m_pTransform, m_nTransforms, nFrame);
}

我一看这个函数,马上就如法炮制,也把它挪进头文件,并加上了inline声明。

在继续进行了一些其他的优化后,我又运行了一下VTune,想要查看优化的结果。然后我惊奇地发现只有GetMatrixKey函数被内联了,GetTransform函数并没有被内联(VTune可以跟踪函数调用,如果函数被内联,则不会出现在函数的CPU利用列表中)。我记得当初学C++时,书上只是很笼统地说内联函数必须结构简单,但又没有定义什么才算“简单”函数。

随后,我去查了一下C++函数要满足什么条件才会被编译器内联,各个论坛中的人众说纷纭,下面是我整理粗略整理后得到的结果:

  • 函数体非常简单,通常为1~5行代码(这个应该不准确,因为我最开始被内联的那个函数就超过5行了,况且代码行数并不能和代码复杂度划等号)
  • 函数中不能包含循环语句、switch语句或异常处理语句(还有人说不能包含if语句,但经本人测试,包含if语句的函数是可以被内联的)
  • 函数中不能调用递归函数

然而,这些规则并不能解释GetTransform函数为什么没有被内联。随后,我又把GetMatrixKey函数取消内联,又进行了一次测试,结果发现GetTransform函数这一次被内联了,这说明内联函数A中可以调用其他函数B,但函数B不能是内联函数。

为此,我又采用了宏定义的方式实现GetTransform函数:

// Author : 大便一箩筐 http://www.cnblogs.com/dbylk
#define GetTransform(Key, nFrame) GetMatrixKey((Key).m_pTransform, (Key).m_nTransforms, nFrame)

结果发现GetTransform被“内联”(宏定义替换)了,GetMatrixKey函数没有被内联。

从上面的尝试可以得出一个结论,内联函数中不能包含其他内联函数,否则只有一个函数会被内联。


补充于2016-03-11:

内联函数可以说是用空间换时间的一种优化方式,因此它并不是一定能够提升程序性能的:如果一个实现比较复杂的函数可能在程序的很多个模块被调用,那么不内联可能会使程序具有更好的性能表现。因为内联会增加程序二进制代码的大小,这样会降低CPU Cache的命中几率,由此导致的开销可能远远超过内联优化得到的收益。

如果有足够的信心自己写的代码内联比不内联效率更高,可以使用C++的__forceinline关键字,这样一来编译器就会忽视优化选项,强制对函数执行内联处理。

最新文章

  1. .NET 数据类型转换 方法
  2. grunt安装和使用教程
  3. CI 笔记一
  4. iOS:崩溃统计工具Crashlytics的使用
  5. css中各种情况下的元素的垂直和水平居中的问题
  6. Server Develop (八) IOCP模型
  7. BZOJ1185 : [HNOI2007]最小矩形覆盖
  8. 求字符串的最长回文字串 O(n)
  9. WinServer 之 访问同网段服务器 或 同一服务器多虚拟机间的访问
  10. MYSQL批处理
  11. CakePHP的文章分类的功能实现
  12. VS2010 发布网站时如何使DLL文件名固定
  13. (hdu step 7.1.5)Maple trees(凸包的最小半径寻找掩护轮)
  14. Matplotlib初体验
  15. ZOJ 3229 Shoot the Bullet [上下界最大流]
  16. 操作 numpy 数组的常用函数
  17. Python必备库
  18. 整数划分 NBUT - 1046
  19. iOS 开发笔记-报错处理
  20. python记录_day25 包

热门文章

  1. 查找文件路径find
  2. 查看Oracle 基表的方法
  3. SQL联接 外联接 内联接 完全联接 交叉联接
  4. T25健身视频全集+课表
  5. POJ 1733 Parity game (带权并查集)
  6. $python正则表达式系列(3)——正则内置属性
  7. bind方法代替闭包
  8. centos 7 install virtualbox
  9. 20145222黄亚奇《网络对抗》web安全基础实践
  10. 2018-2019-2 20165114《网络对抗技术》Exp4 恶意代码分析