性能调优难题


下图为vs2010采用CPU采样的性能分析报告(release版本),其中红线部分相当困惑,为什么开销这么大?



release的反汇编如下:



debug的反汇编如下:


从反汇编来看,release将cmp优化成test。

26 个解决方案

#1


慢的不是cmp是jne

#2


??
第33行代码同样有jne指令,并且还是cmp而不是test,为何这两行(26、33)的开销对比如此大(这两行执行的次数完全一样多)

#3


Sorry,首页的反汇编搞错类了,不过都差不多,还是以上问题,对比首页33行的反汇编和26行的反汇编,为什么这两行代码的执行效率差别这么大。
一下重贴26行的反汇编


#4


在用人脑判断效率瓶颈之前,请先用Profiler工具。

#5


引用 4 楼 zhao4zhong1 的回复:
在用人脑判断效率瓶颈之前,请先用Profiler工具。


首页就是profile工具的分析结果

#6


if的命中率的问题吧

#7


用C语言1000行源码能完成的工作千万不要用C++重写!

#8


引用 6 楼 zilaishuichina 的回复:
if的命中率的问题吧


很不幸,不是


反汇编出来只是将jne改成了je

#9


引用 7 楼 zhao4zhong2 的回复:
用C语言1000行源码能完成的工作千万不要用C++重写!


您回错帖了吧!

#10


引用 9 楼 moolleychean 的回复:
引用 7 楼 zhao4zhong2 的回复:用C语言1000行源码能完成的工作千万不要用C++重写!

您回错帖了吧!

所以这个肯定是假马甲嘛。

#11


这个差别貌似可以忽略不计。
那个1.1%就算降到0.1%也没有意义。

#12


我只注意到楼主提供图片中的
 6.1% 32 ……
39.1% 40 ……

#13


引用 11 楼 raison_x 的回复:
这个差别貌似可以忽略不计。
那个1.1%就算降到0.1%也没有意义。


道理没错,不是主要的开销,但是不明不白的出现这么一个不合情理的开销,心里头不舒服。

#14


引用 12 楼 zhao4zhong1 的回复:
我只注意到楼主提供图片中的
 6.1% 32 ……
39.1% 40 ……


6.1%的这个差不多到极限了,对象的数目太多了,上百万。
改用boost::unordered_map效率稍微好点,不过会增clean线程和锁的开销,总体差不多。

39.1%的是后面的主处理流程,正在进一步优化。

#15


引用 13 楼 moolleychean 的回复:
引用 11 楼 raison_x 的回复:这个差别貌似可以忽略不计。
那个1.1%就算降到0.1%也没有意义。

道理没错,不是主要的开销,但是不明不白的出现这么一个不合情理的开销,心里头不舒服。


test & jne/je 不可能会带来这么大的开销,可能这个问题不在于 line 26,而在于 line 25. 你在 line 25 后面弄个简单的语句试试看,比如一个简单的加法运算,有可能这个简单的加法会让我们吃一惊。

#16


一个简单语句被调用100000次也会比复杂指令调用1次耗时

#17


单纯看汇编不会这么慢,是不是后面的跳转遇到上下文切换了。Lz多测几次,取个平均看看

#18


擒贼先擒王!

#19


引用 15 楼 raison_x 的回复:
引用 13 楼 moolleychean 的回复:引用 11 楼 raison_x 的回复:这个差别貌似可以忽略不计。
那个1.1%就算降到0.1%也没有意义。

道理没错,不是主要的开销,但是不明不白的出现这么一个不合情理的开销,心里头不舒服。

test & jne/je 不可能会带来这么大的开销,可能这个问题不在于 line 26,而在于 line……


这个可能在点子上了,我也怀疑是数组取值的问题,这个数组有1M,参看下面一个64k的数组取值:


红色部分效率不高,之前是这么写的:

    if (cell_id_array_[bvci] == 0) {
        helper_->update_bssgp_dl_unitdata__stats(BSSGP_DL_UNITDATA_CELL_UNFOUND);
        return;
    }
    bssgp_unitdata_head.cell_id = cell_id_array_[bvci];

那个0.6%的CPU占用就出在if (cell_id_array_[bvci] == 0)这一行。

是否可能页面错误导致?这一块我不是很熟悉,但是我将windows的虚拟内存完全禁用后,程序的页面错误变化不大。
是否可能CPU cache命中率太低导致?对于这种大数组,不可能全部读进cache。

#20


引用 18 楼 zhao4zhong1 的回复:
擒贼先擒王!


我对于技术的态度是,知其然,更要知其所以然。虽然我的行业是移动通信,但是对于C++开发的态度是一致的。

#21


引用 17 楼 givemekey 的回复:
单纯看汇编不会这么慢,是不是后面的跳转遇到上下文切换了。Lz多测几次,取个平均看看


测了很多次了,差不多没有什么变化。

#22


引用
引用 15 楼 raison_x 的回复:
    引用 13 楼 moolleychean 的回复:引用 11 楼 raison_x 的回复:这个差别貌似可以忽略不计。
    那个1.1%就算降到0.1%也没有意义。
    道理没错,不是主要的开销,但是不明不白的出现这么一个不合情理的开销,心里头不舒服。
    test & jne/je 不可能会带来这么大的开销,可能这个问题不在于 line 26,而在于 line……
这个可能在点子上了,我也怀疑是数组取值的问题,这个数组有1M,参看下面一个64k的数组取值:
......
是否可能页面错误导致?这一块我不是很熟悉,但是我将windows的虚拟内存完全禁用后,程序的页面错误变化不大。
是否可能CPU cache命中率太低导致?对于这种大数组,不可能全部读进cache。

如果你监测到了页面错误较多,说明内存吃紧,已经发生了较多的磁盘交换内存页面了,那会有影响,用 profiler 监测的时候,profiler 和你的程序是一起跑的,profiler要做更多的工作,消耗更多的内存,这也会导致你的程序内存紧张。
CPU cache命中率对单条语句的影响不会这么夸张,这么大的影响更有可能是背后发生了磁盘操作。如果可能的话,修改一下程序,改成直接的物理内存(不用malloc/new)试试看。

#23


引用 22 楼 raison_x 的回复:
引用引用 15 楼 raison_x 的回复:
    引用 13 楼 moolleychean 的回复:引用 11 楼 raison_x 的回复:这个差别貌似可以忽略不计。
    那个1.1%就算降到0.1%也没有意义。
    道理没错,不是主要的开销,但是不明不白的出现这么一个不合情理的开销,心里头不舒服。
    test & jne/je 不可……



“如果你监测到了页面错误较多,说明内存吃紧”,这句是错误的。
这个图还是在将windows虚拟内存完全禁用后截取的:

以下问题搞不明白:
将windows虚拟内存完全禁用后,内存会交换到什么地方?
如果没有磁盘分页文件可以交换,为什么还会出现page fault?

#24


引用 23 楼 moolleychean 的回复:
引用 22 楼 raison_x 的回复:引用引用 15 楼 raison_x 的回复:
    引用 13 楼 moolleychean 的回复:引用 11 楼 raison_x 的回复:这个差别貌似可以忽略不计。
    那个1.1%就算降到0.1%也没有意义。
    道理没错,不是主要的开销,但是不明不白的出现这么一个不合情理的开销,心里头不舒服。
   ……


忘了说配置了:


#25


引用
引用 22 楼 raison_x 的回复:

    引用引用 15 楼 raison_x 的回复:
        引用 13 楼 moolleychean 的回复:引用 11 楼 raison_x 的回复:这个差别貌似可以忽略不计。
        那个1.1%就算降到0.1%也没有意义。
        道理没错,不是主要的开销,但是不明不白的出现这么一个不合情理的开销,心里头不舒服。
        test & jne/je 不可……
“如果你监测到了页面错误较多,说明内存吃紧”,这句是错误的。
以下问题搞不明白:
将windows虚拟内存完全禁用后,内存会交换到什么地方?
如果没有磁盘分页文件可以交换,为什么还会出现page fault? 


以下假设所说的页面错误指 Page Fault.
如果已经将虚拟内存完全禁用了,那应该不存在内存和页面文件的交换。这时出现 page fault 可以忽略,它仍然是从物理内存读写,而且我们也没有确定是在那个时间点发生了 page fault。
你的 i7 有6M的cache,程序应该还是蛮大机会占用一点的。如果是因为数组太大导致cache的切换,而导致CPU消耗偏多的话,也是有可能的,0.8/0.1 = 8,和内存/cache速率比也相近。进行每条语句的消耗时间探测的话,每条语句之间都要有探针代码,实际在CPU里面运行的情况要比汇编代码所显示的复杂。
虽然未能肯定是何原因,但是和内存存取紧密相关这一点是最可能的。或者试下改变 line 25 的数组的大小,从1k到1M不等,对比看看。

#26


引用 25 楼 raison_x 的回复:
引用引用 22 楼 raison_x 的回复:

    引用引用 15 楼 raison_x 的回复:
        引用 13 楼 moolleychean 的回复:引用 11 楼 raison_x 的回复:这个差别貌似可以忽略不计。
        那个1.1%就算降到0.1%也没有意义。
        道理没错,不是主要的开销,但是不明不白的出现这么……


之前的两个问题已经弄明白了,page fault 分为 hard和soft两种。

首页的问题我现在更倾向于CPU采样的不准确性导致的。
在整个测试过程中除了帖子中列出的,实际上还有一些不太理解的较大的开销,比如:

update_user_ip_kpi函数逻辑也很简单,一些比较和加法语句而已,但是与主处理逻辑相比开销是其差不多30%。
使用检测方式重新测量的结果如下:

两者的比值就只有不到7%了。
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告