欢迎来到天天文库
浏览记录
ID:26053053
大小:86.74 KB
页数:14页
时间:2018-11-24
《强者恒强:x86高性能编程笺注之循环(下)》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、强者恒强:x86高性能编程笺注之循环(下)读者须知:《强者恒强:x86高性能编程笺注》是云杉网络推出的系列技术分享,该系列文章将分享x86高性能开发方面的实践和思考。主要内容目录如下,欢迎各位业界同仁与我们讨论交流相关话题。l什么是性能l流水线l分支l循环l缓存l预取l大页l锁lRCUl无锁lSIMD指令LoopUnrolling循环展开是一种应用最多,流传最广泛的循环性能优化技巧。优化方式也很好理解,将多次循环的处理内容铺延到一次循环中处理,减少对迭代器值的判断和分支选择,就是循环展开。循环展开之后可以成倍减少循环
2、的overhead,让CPU资源能更专注于循环体的处理工作,推荐在循环体指令较少的时候操作——教科书上一般都是这么说的。 理论其实都没错,但我们在这里侧重一下实践。用perf等工具去实际探究一下性能热点究竟产生在哪里,以及优化之后的效果。虽然如今硬件和软件的发展速度已经开始让一些“奇技淫巧”加速过时,但我们在乎的也只是那一点点同时摆在时间和硅基处理器面前的禁脔而已。 使用-O0选项编译如下循环:loop1:for (i= 0; i< 100000000; i++) { sum+= array[i];}在我的机器上用
3、perfstat观察一下大体情况,可以得到如下结果:SideNotes:perfstat可以添加repeat[N]参数指定重复执行次数,显示平均结果,添加-d显示更详细结果。Performancecounterstatsfor'./loop10':348.773618task-clock#0.999CPUsutilized5context-switches#0.014K/sec0cpu-migrations#0.000K/sec1,203page-faults#0.003M/sec796,895,241cycles#
4、2.285GHz[83.37%]495,310,308stalled-cycles-frontend#62.16%frontendcyclesidle[83.37%]44,325,164stalled-cycles-backend#5.56%backendcyclesidle[66.74%]802,774,532instructions#1.01insnspercycle#0.62stalledcyclesperinsn[83.37%]100,538,550branches#288.263M/sec[83.37%]2
5、,014branch-misses#0.00%ofallbranches[83.18%]0.349124017secondstimeelapsed在正常的终端显示里,perf很贴心地把62.16%的front-endstalledcycles标成了难以抗拒的斩男色。从前面的关于流水线的介绍中我们可以得知,front-end主要负责指令的fetch和解码,并给执行核心输送指令。既然front-endstalled那么多,我们就选择perf事件来做一下测量看看具体是哪里在浪费CPU好了:perfrecord-eidle-
6、cycles-frontend./loop10perfreport SideNotes:objdump-S 可以打印出目标文件的汇编代码 │ push %rbp │ mov %rsp,%rbp │ uint64_tsum=0; │ movq $0x0,-0x8(%rbp) ; 初始化sum= 0 │ inti=0; │ movl $0x0,-0xc(%rbp) ; 初始化i= 0 │ for(;i7、15: mov -0xc(%rbp),%eax; 在%eax中写入i的值 │ cltq │mov 0x601060(,%rax,4),%eax; 读取array[i]的值并写入%eax 26.95│ cltq 17.59 │ add %rax,-0x8(%rbp) ; 计算sum+=array[i] │ uint64_t │ loop_process() │ { │ uint64_tsum=0; │ inti=0; │ for(;i8、.82│ addl $0x1,-0xc(%rbp) ; i自增 │2b: cmpl $0x5f5e0ff,-0xc(%rbp) ; 判断循环条件 │ ↑jle 15 ; 返回循环起始位置 │ sum+=array[i]; │ } │ returnsum; │ mov -0x8(%rbp),%rax; s
7、15: mov -0xc(%rbp),%eax; 在%eax中写入i的值 │ cltq │mov 0x601060(,%rax,4),%eax; 读取array[i]的值并写入%eax 26.95│ cltq 17.59 │ add %rax,-0x8(%rbp) ; 计算sum+=array[i] │ uint64_t │ loop_process() │ { │ uint64_tsum=0; │ inti=0; │ for(;i8、.82│ addl $0x1,-0xc(%rbp) ; i自增 │2b: cmpl $0x5f5e0ff,-0xc(%rbp) ; 判断循环条件 │ ↑jle 15 ; 返回循环起始位置 │ sum+=array[i]; │ } │ returnsum; │ mov -0x8(%rbp),%rax; s
8、.82│ addl $0x1,-0xc(%rbp) ; i自增 │2b: cmpl $0x5f5e0ff,-0xc(%rbp) ; 判断循环条件 │ ↑jle 15 ; 返回循环起始位置 │ sum+=array[i]; │ } │ returnsum; │ mov -0x8(%rbp),%rax; s
此文档下载收益归作者所有