繁体   English   中英

我应该如何解释OProfile输出?

[英]How am I supposed to interpret OProfile output?

我最近尝试使用OProfile对应用程序进行性能分析。 收集到的数据对我来说已经非常有价值,但是我很难对其进行准确的解释。 使用oprofile设置并运行我的应用程序后,我生成了报告并得到:

root @ se7xeon:src#opreport图片:test -l -t 1
溢出状态不可用
CPU:具有4个超线程的P4 / Xeon,速度3191.66 MHz(估计)
计数的GLOBAL_POWER_EVENTS事件(不停止处理器的时间),单位掩码为0x01(强制性),计数为750000
样品%符号名称
215522 84.9954 cci :: Image :: interpolate(unsigned char *,cci :: Matrix const&)const
17998 7.0979 cci :: Calc :: diff(unsigned char const *,unsigned char const *)
13171 5.1942 cci :: Image :: getIRect(unsigned char *,int,int)const
5519 2.1765 cci :: Image :: getFRect(unsigned char *,double,double)const

好的,所以我的插值函数负责应用程序84%的执行时间(过长)。 然后似乎可以考虑一下:

root @ se7xeon:src#opannotate图像:test --source
[...]

/* cci::Image::interpolate(unsigned char*, cci::Matrix<cci::Point2DF> const&) const total: 215522   84.9954 */  
1392  0.5529 :void Image::interpolate(CCIPixel *output, const Matrix<Point2DF> &inputPoints) const throw()  
4  0.0016 :{  
[...]  
:                col0 = static_cast<int>(point[idx].x);  
3  0.0012 :      col1 = col0+1;  
629  0.2498 :    row0 = static_cast<int>(point[idx].y);  
385  0.1529 :    row1 = row0+1;  
56214 22.3266 :  if (col0 < 0 || col1 >= m_width || row0 < 0 || row1 >= m_height)  
:                {  
:                        col0 = row0 = col1 = row1 = 0;  
:                }  

如果我理解正确,则if条件占程序执行时间的22%以上。 开括号和函数声明似乎要花费时间,是否应该对应于函数调用开销(“堆栈上的推入参数,跳转,弹出参数”序列)?

我更改了源代码中的某些内容(与后来的瓶颈有关,因为我不知道如何优化if),重新编译,再次通过oprofile运行(不要忘记opcontrol --reset)。 现在,带注释的代码在同一位置看起来像这样:

6  0.0024 :     curPx = point[idx].x;  
628  0.2477 :   curPy = point[idx].y;  
410  0.1617 :   col0 = static_cast<int>(curPx);  
57910 22.8380 : col1 = col0+1;  
:               row0 = static_cast<int>(curPy);  
:               row1 = row0+1;  
:               if (col0 < 0 || col1 >= m_width || row0 < 0 || row1 >= m_height)  
:               {  
:                   col0 = row0 = col1 = row1 = 0;  
:               }  

这次,if根本不花时间(?),最昂贵的指令是“ col1 = col0 + 1”,整个耗时块似乎都已向上移动。 怎么会这样? 可以完全信任此漏洞以查明源中的瓶颈吗?

我的另一个疑问是,当我设置opcontrol时,我将跟踪事件输入为GLOBAL_POWER_EVENTS,样本数量为750k。 在输出中,插值函数似乎占了84%,但其中记录的样本数量仅略高于200k。 那甚至不是请求数量的50%。 我是否了解剩余的〜500k样本是由输出中未列出的应用程序(内核,Xorg等)采集的?

在分析优化的代码时,您实际上不能依赖准确的源代码行。 编译器将内容移动太多。

为了获得准确的图像,您将需要查看代码反汇编程序输出。

OProfile可以(他们告诉我)在墙上时钟时间(不是CPU)上获取堆栈样本,并且它可以为您提供行级百分比。 您正在寻找的是包含在大部分堆栈样本中的行。

在手动调整代码之后,我才会打开编译器优化,因为它只是隐藏了东西。

当您说插值例程使用84%的时间时,会触发一个问题。 整个程序需要一些时间,对吗? 这需要100%的时间。 如果将程序的时间减少一半,或者将其时间增加一倍,则仍将花费100%的时间。 84%的插值是否过多取决于是否进行了过多的操作。

因此,我建议您不要问例程的百分比是否太大。 相反,您会寻找花费大量时间的代码行,并询问是否可以对其进行优化。 看到不同? 优化代码后,它可以大大减少总体运行时间,但仍可能占总运行时间的很大一部分。 当什么都不花很大的钱时,代码不是最佳的。 当所有花费很大的事情都无法改善时,代码是最佳的。

我不在乎只给出数字的东西。 我想要的是洞察力。 例如,如果该例程占84%的时间,那么如果您对堆栈进行10个采样,则该采样将占8.4个。 确切的数字无关紧要。 重要的是要了解为什么它在那里。 真的真的有必要去很多地方吗? 这就是查看堆栈样本可以告诉您的内容。 也许您实际上需要进行两次内插? 人们通常通过分析原因来发现,他们试图加速的例程几乎不需要调用,甚至根本不需要调用。 我猜不到你的情况。 只有检查程序状态的洞察力可以告诉您。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM