三沣开发知识 购物 网址 游戏 小说 歌词 地图 快照 开发 股票 美女 新闻 笑话 | 汉字 软件 日历 阅读 下载 图书馆 编程 租车 短信 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题
autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml
html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
  IT知识库 -> C++ -> 程序性能优化 -> 正文阅读
 

[C++]程序性能优化

程序性能优化   在硬件资源昂贵的时代,编程人员非常注重程序的性能,以期望用尽可能少的硬件资源完成尽可能多的事情。随着科技的发展,
摩尔定律的魔力使得硬件资源已越来越便宜,速度也越来越快,似乎性能已不是编程人员所需关注的事情了。然而在一个竞争
与发展的时代,软件的功能越来越复杂,用户的操作体验越来越重要,而且竞争越来越激烈,谁能以更优势的价格,更好的操
作体验,完成更多更复杂的事情,谁就将在激烈竞争中胜出。因而软件的性能优化必将一直是软件领域所要关注的内容之一。
虽然软件的性能优化贯穿了设计与编码的整个过程,本文也将从设计与编码两个层次对性能优化进行分析。本文还将从CPU、内
存、磁盘、网络四个方面描述性能问题分析的过程。
2.设计出来的性能
1)系统架构
控制流与数据流?减少不必要的模块
2)程序结构
多线程程序
锁的粒度、各种锁/信号量的性能对比
共享内存通信
降低灵活性以获取高性能。
减少不必要的重复判断(SHTTP/HTTP)
3)接口设计
好的接口给予使用者充分的灵活性
4)数据结构与算法
Linux内存管理,数量小时使用链表
3.编码的艺术
1)内存访问与文件
减少new/delete或malloc/free操作减少换页
减少文件打开与关闭操作
减少文件读写次数(减少系统调用)
2)减少不必要的运算
消除重复运算
循环中的运算
最忙的循环放在里面
3)语言及库函数特性的利用
if与case语句
构造与析构
宏与内联函数
迟缓型计算
减少临时变量
缓存字符串的长度
不必要的memset
4)硬件特性的利用
字节对齐
移位与乘除2
性能热点用汇编实现
4.性能分析工具-callgrind
valgrind系列工具因为免费,所以在linux系统上面最常见。callgrind是valgrind工具里面的一员,它的主要功能是模拟cpu的cache,能够计算多
级cache的有效、失效次数,以及每个函数的调用耗时统计。
callgrind的实现机理(基于外部中断)决定了它有不少缺点。比如,会导致程序严重变慢、不支持高度优化的程序、耗时统计的结果误差较大等,
更多的外部工具有oprofile,gprof,tprof,Rational Quantify and Intel VTune
5.编译器参数的优化
大家要记住的是,编译器绝对比想象的要强大的多。编写编译器的人大都是十年、几十年代码编写经验的科学家!你能简单想到的,他们都已经想
到过了。普通的编译器,可以支持大部分已知的优化策略以及多媒体指令。至于哪个编译器更好,大部分人的观点是:intel。Intel毕竟是最优秀的
cpu提供者,他们的编译器考虑了很多cpu的特性,跑的更快。但目前intel编译器有一些比较弱智的地方,即它只识别自己的cpu,不是自己的cpu,
就认为是最差的i386-i686机器,从而不能在amd等平台上面支持sse功能。我们在linux上面写代码,一般更加喜欢流行的编译器,比如gcc。
Gcc的优点是它更新快,开源,bug修改迅速。正因为他更新快,所以它能够支持部分C03的规范。
5.1 gcc支持的优化技术
1) 函数内联
函数调用的过程是:压入参数到堆栈、保护现场、调用函数代码、恢复现场。当一个函数被大量调用的时候,函数调用的开销特别巨大。函数内
联是指把这些开销都去除,而直接调用代码。函数内联的不好之处是难以调试,因为函数实际上已经不存在了。
2) 常量预先计算
a = b + 1000 * 8
对于这段代码,程序会预先计算b + 1000 * 8,从而变成:
a = b+ 8000
3) 相同子串提取
a=(b+1)*(b+1)
这里,b+1需要计算2次,可以只用计算一次:
tmp=b+1
a=tmp*tmp
4) 生存周期分析
这是一个比较高级的技术。假设有代码:
a=b+1
c=a+1
在执行的时候,因为第二句依赖第一句,所以2句是线性执行。
但编译器其实可以知道,c就是等于b+2,所以代码变成:
a=b+1
c=b+2
这样,这2句就没有任何关系来了,执行的时候,cpu可以并行执行它们。
5) 清除跳转
看如下代码:
int func()
{
int ret = 0;
if(xxx)
ret=5;
else if(yyy)
ret=6;
return ret;
}
当条件xxx满足的时候,程序还会跳到下面执行,但其实是没有必要的。编译器会把它变成:
int func()
{
if(xxx)
return 5;
else if(yyy)
return 6;
}
6) 循环展开
循环由几个部分组成:计数器赋值、计算器比较、跳转。每次循环,后面2步都是必须的消耗。把循环内的代码拷贝多份,可以大大减少
循环的次数,节约后面2步的耗时。参考:
for(int counter = 0; counter < 4; count++)
xxx;
可以变成:
xxx;
xxx;
xxx;
xxx;
编译器不仅仅可以展开普通循环,它还能展开递归函数。原理是一样的,递归其实是一个不定长的借用了堆栈的循环。
7) 循环内常量移除
for(int idx=0;idx<100;idx++)
a[idx]=a[idx]*b*b;
因为b*b在循环体内的值固定(常量),所以代码可以变成:
tmp=b*b;
for(int idx=0;idx<100;idx++)
a[idx]=a[idx]*tmp;
8) 并行计算
大家都知道,现代cpu支持超流水线技术,同时可以执行多条语句。多条语句能否同时执行的限制是不能互相依赖。编译器会自动帮我们把
看起来单线程执行的代码,变成并行计算,参考:
d=a+b;
e=a+d+f;
可以变成:
tmp=a+f;
d=a+b;
e=d+tmp;
9) 表达式简化
当年笔者在学习《离散数学》和《数字电路》的时候,总被眼花缭乱的布尔运算简化题目难倒。gcc终于让我松了一口气。参考:
!a && !b
这句需要3步执行,但变成:
!(a || b)
只需要2步执行。
5.2 gcc重要优化选项
1) 内联
-finline-small-functions
内联比较小的函数。-O2选项可以打开。
-findirect-inlining
间接内联,可以内联多层次的函数调用。-O2选项可以打开。
-finline-functions
内联所有可以内联的函数。-O3选项可以打开。
-finline-limit=N
可以进行内联的函数的最小代码长度。注意,这里是伪代码,不是真实代码长度。伪代码是编译器经过处理后的代码。带inline等标志的函数,默认
300行代码即可内联,不带的默认50行代码。和这个相关的选项是max-inline-insns-single和max-inline-insns-auto。
max-inline-insns-recursive-auto
内联递归函数时,函数的最大代码长度。
large-function-insns、large-function-growth、large-unit-insns等
函数内联的副作用是它导致代码变多,程序变长。这里的几个参数可以控制代码的总长度,避免编译后出现巨大的程序,影响性能和浪费资源。
2) -fomit-frame-pointer
不采用标准的ebp来记录堆栈指针,节省了一个寄存器,并且代码会更短。但据说在某些机器上面会导致debug模式出错。实际测试表明,在gcc4.2.4以
下,O2和O3都无法打开这个选项。
3) -fwhole-program
把代码当做一个最终交付的程序来编译,即明确指定了不是编译库。这个时候,编译器可以使用更多的static变量,来加快程序速度。
4) mmx/ssex/avx
多媒体指令,主要支持向量计算。一般来说,-march=i686、-mmx、-msse、-msse2是目前机器都支持的指令。
除了基本的多媒体支持外,gcc编译器还支持-ftree-vectorize,这个选项告诉编译器自动进行向量化,也是-O3支持的选项。
多说几句。在平常的使用中,多媒体指令不是很常见(除非游戏)。如果你有几个位表(bitset),它们需要进行各种位操作的话,多媒体指令还是挺有效果滴。
5.3 gcc大杀器-profile driven optimize
这是比较晚才出现的技术。其基本原理是:根据实际运行情况,缩短hot路径的长度。编译器通过加入各种计数器来监控程序的运行,然后根据计算出来
的实际访问路径情况,来分析hot路径,并且缩短其长度。根据gcc开发者的说法,这种技术可以提高20-30%的运行效率。
其使用方式为:
编译代码,加上-fprofile-generate选项
到正式环境一段时间
当程序退出后,会产生一个分析文件
利用这个分析文件,加上-fprofile-use,重新编译一次程序
举个例子来说:
a=b*5;
如果编译发现b经常等于10,那么它可以把代码变成:
a=50;
if(b != 10)
a=b*5;
从而在大多数情况下,避免了乘法消耗。
5.4 gcc支持的优化属性(__attribute__)
aligned
可以设置对齐到64字节,和cpu的cache line看齐
fastcall
如果函数调用的前面2个参数是整数类型的话,这个选项可以用寄存器来传递参数,而不是用常规的堆栈
pure
函数是纯粹的函数,任何时刻,同样的输入,都会有同样的输出。可以很方便依据概率来优化它。
5.5 gcc其他优化技术
#pragma pack()
对齐到一个字节,节省内存
__builtin_expect
直接告诉编译器表达式最可能的结果,方便优化
编译带debug信息的小文件
以下代码能够大大减少编译后程序大小,同时保留debug信息。其原理是外链一个带debug的版本。
g++ tst.cpp -g -O2 -pipe
copy a.out a.gdb
strip --strip-debug a.out
objcopy --add-gnu-debuglink=a.gdb a.out
6.算法是核心
算法是程序的核心,一个程序的好坏,大部分是看起算法的好坏。对于一般的程序员来讲,我们无法改变系统和库的调用,只能根据
规则来使用它们,我们可以改变的是我们自己核心代码的算法。
算法能够十倍甚至百倍的提高程序性能。如快排和冒泡排序,在上千万规模的时候,后者比前者慢几千倍。
通常情况下,有如下一些领域的算法:
A)常见数据结构和算法
B)输入输出
C)内存操作
D)字符串操作
E)加密解密、压缩解压
F)数学函数
总上所述:性能问题通常体现在四个方面:CPU、内存、磁盘、网络几个方面。解决方法可以是修改代码甚至程序结构以更充分的利用现有资源,
也可以是增加相应的硬件以增加资源供给。
  C++ 最新文章
关于poin与references
019:别叫,这个大整数已经很简化了!
c++智能指针详解
BZOJ1269: [AHOI2006]文本编辑器editor
洛谷P3835 【模板】可持久化平衡树
洛谷P2925 [USACO08DEC]干草出售Hay For Sa
威尔逊定理
c++ Windows Socket实现最简单的C/S网络通信
洛谷P1306 斐波那契公约数
C++中引用传递与指针传递区别
上一篇文章      下一篇文章      查看所有文章
加:2015-03-30 01:45:02  更:2017-05-15 11:58:05 
 
技术频道: 站长资讯 .NET新手区 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA Visual Studio ASP.NET MVC .NET控件开发 Entity Framework WinRT/Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动设计 Html/Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP Oracle ERP Dynamics CRM K2 BPM 信息安全 企业信息化其他 Android开发 iOS开发 Windows Phone Windows Mobile 其他手机开发 敏捷开发 项目与团队管理 软件工程其他 SQL Server Oracle MySQL NoSQL 其它数据库 Windows 7 Windows Server Linux
脚本语言: vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程
网站开发: CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流 开发者乐园 Android开发资料
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年5日历
2018-5-24 4:09:23
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT知识库