- 1、本文档共47页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C性能优化专业技术导论
C++性能优化技术导论
来源:HYPERLINK /a/zh_CN/datea/zh_CN/date作者:冲出宇宙
【介绍】
本文完整的描述了C++语言的性能优化方法,从编译器、算法、语言特性、硬件、Linux等多个角度去考虑问题,文章技术含量很高,值得一看。
【目录】
第一章 性能优化原理
第二章 善用编译器
第三章 算法为王
第四章 c++语言特性
第五章 理解硬件
第六章 linux系统
1、性能优化原理
在谈论性能优化技术之前,有几点大家一定要明确。第一点是必须有编写良好的代码,编写的很混乱的代码(如注释缺乏、命名模糊),很难进行优化。第二点是良好的构架设计,性能优化只能优化单个程序,并不能够优化蹩脚的构架。不过,网络如此发达,只要不是自己乱想的构架,只要去积极分析别人的成功构架,大家几乎不会遇到蹩脚的构架。
1.1、计算函数、代码段调用次数和耗时
函数的调用次数比较好说,用一个简单的计数器即可。一个更加通用的框架可能是维护一个全局计数,每次进入函数或者代码段的时候,给存储的对应计数增加1。
为了精确的计算一段代码的耗时,我们需要极高精度的时间函数。gettimeofday是其中一个不错的选择,它的精度在1us,每秒可以调用几十万次。注意到现代cpu每秒能够处理上G的指令,所以1us内cpu可以处理几千甚至上万条指令。对于代码长度少于百行的函数来说,其单次执行时间很可能小于1us。目前最精确的计时方式是cpu自己提供的指令:rdtsc。它可以精确到一个时钟周期(1条指令需要消耗cpu几个时钟周期)。
我们注意到,系统在调度程序的时候,可能会把程序放到不同的cpu核心上面运行,而每个cpu核心上面运行的周期不同,从而导致了采用rdtsc时,计算的结果不正确。解决方案是调用linux系统的sched_setaffinity来强制进程只在固定的cpu核心上运行。
有关耗时计算的参考代码:
// 通常计算代码耗时
uint64_t preTime = GetTime();
//代码段
uint64_t timeUsed = GetTime() - preTime;
// 改进的计算方式
struct TimeHelper{
uint64_t preTime;
TimeHelper():preTime(GetTime())
{}
~TimeHelper(){
g_timeUsed = GetTime() - preTime;
}
};
// 调用
{
TimeHelper th;
// 代码段
}
// g_timeUsed保存了耗时
// 得到cpu的tick count,cpuid(重整时钟周期)消耗约300周期(如果不需要特别精确的精度,可以不执行cpuid
inline uint64_t GetTickCPU()
{
uint32_t op; // input: eax
uint32_t eax; // output: eax
asm volatile(
pushl %%ebx \n\t
cpuid \n\t
popl %%ebx \n\t
: =a(eax) : a(op) : cc );
uint64_t ret;
asm volatile (rdtsc : =A (ret));
return ret;
}
// 得到cpu的主频, 本函数第一次调用会耗时0.01秒钟
inline uint64_t GetCpuTickPerSecond()
{
static uint64_t ret = 0;
if(ret == 0)
{
const uint64_t gap = 1000000 / 100;
uint64_t endTime = GetTimeUS() + gap;
uint64_t curTime = 0;
uint64_t tickStart = GetTickCPU();
do{
curTime = GetTimeUS();
}while(curTime endTime);
uint64_t tickCount = GetTickCPU() - tickStart;
ret = tickCount * 1000000L / (curTime - endTime + gap);
}
return ret;
}
1.2、其他策略
除了基本的计算执行次数和时间外,还有如下几种分析性能的策略:
a、基于概率
通过不断的中断程序,查看程序中断的位置所在的函数,出现次数最多的函数即为耗时最严重的函数。
b、基于事件
当发生一次cpu硬件事件的时候,某些cup会通知进程。如果事件包括L1失效多少次这种,我们就能知道程
文档评论(0)