分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow
转载:http://blog.csdn.net/heiyeshuwu/article/details/7088192
【介绍】
本文完整的描述了C++语言的性能优化方法,从编译器、算法、语言特性、硬件、Linux等多个角度去考虑问题,文章技术含量很高,值得一看。
来源:http://www.whysearch.org/a/zh_CN/date/20110824
作者:冲出宇宙
【目录】
第一章 性能优化原理
第二章 善用编译器
第三章 算法为王
第四章 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