代码的重量如何称?

本文探讨了软件测量中的“重量”概念,特别是在Windows Performance Analyzer (WPA) 中的Weight指标。通过分析发现,该指标实际衡量的是CPU时间消耗,并以毫秒为单位。文章详细解释了Weight指标的计算方法及其在软件性能分析中的应用。

测量是个古老而且永恒的话题。精确测量永远很难。因为与太多因素有关,比如测量指标,测量工具,测量环境,测量过程,还有测量者的心态和水平。拿菜场买菜来说,测量者很可能故意放大测量误差。:-)

如果要测量的是软件,那就更复杂了。首先一个问题就是还没有大家普遍认可的测量指标和测量单位。举例来说,要测量一棵白菜,那么可以测量它的重量,不嫌麻烦也可以测量它的体积,重量和体积都是公认的测量指标。而软件呢?不是实物,抓不起来,飘忽不定,鬼影一般,重量体积这些传统的测量方法都不适用了。所以没法你说一个软件高几何,重几许,谁也不知道微信有几斤重?

4da6864ebd663d285a47d4bdb7291dae.png

传统的测量方法是经过长期积累形成的,已经深入到我们的文化和思维之中。我们不能把它们直接搬来测量软件,但是它们一定会影响我们的思考,影响软件测量方法的发展,有些概念和名称很可能也会被拿过来用。

比如在微软的著名调优工具WPA(Windows Performance Analyzer)中,就有一个重量(Weight)指标(下面截图表格的第4列)。

727bbe8b18a9e976699c78a0f7e3b3b6.png

“In science and engineering, the weight of an object is usually taken to be the force on the object due to gravity.”

上面是Wikipedia对Weight的解释,可是在这里显然说不通。:-) 那它是什么意思呢?很感谢一位同行询问这个问题,让我特别注意到了这个指标。但是颇为惭愧的是,当时我并没有能立即回答出这个问题。(囧)

在著名的VTune工具中,测量的指标更多,但是只要把鼠标移动到标题列上的指标名,就会给出非常详细的解释。比如下面截图中弹出的是对著名的CPI rate(每条指令所用的时钟周期个数)的解释,包含全称、含义、取值范围,计算公式等。

9fbe0dee43d8d559b2d1ae6c637eb10b.png

尝试在WPA中做类似操作,6.2.8400版本没有弹出任何提示,6.3.9600版本确实可以弹出一个tooltip,可是上面的信息只是把标题重复了一遍,令人失望。微软啊微软,这工作做的太粗了呀!

bef34fa835929c786809193dbb7d84cf.png

下一个办法是找帮助文件,F1之后,浏览器启动,打开了在线的帮助,坦率说,我很不喜欢把基本的帮助文档也放在网站上。更糟糕的是,网站上的帮助文档也极其粗糙,根本没有对每个测量指标的详细描述。

再下一个方法是搜索引擎了。果真有效,一位名叫Bruce Dawson的美国同行似乎也经历过类似的困惑,并写了一系列名为“The Lost Xperf Documentation”(Xperf为WPT的曾用名)的博客文章。在Bruce先生的文章中,他如此给出Weight指标的详细描述:

  • Weight (in view) – this is an estimate of how much CPU time was spent in the current grouped row. It is a statistical estimate because a sampling profiler, by its nature, has no idea what is happening between samples. If you have enough samples and if your code is not synchronized to a timer then it will be reasonably accurate. The units are milliseconds

感谢Bruce,他用很易懂的语言,比较详细地描述了这个指标,特别还指出了它的单位为毫秒。以此来解释上图中的结果,以BettleMania那一行为例,样本数量(Count)为52827个,Weight为52917毫秒,大约52秒,是合理的。

但是为什么这两个数字有相似性,但却没有精确的对应关系呢?或者说,Weight指标到底是如何计算出来的呢?Bruce只是说这个指标是估计的,但是却没有说是如何估计的?

于是我继续搜索Weight指标的测量方法。Bruce的文章似乎是可以在互联网找到的最详细说明了。没有搜索到现成的答案,那么接下来要靠自己了。

怎么解决这个问题呢?我想到了把WPA的测量值和使用其它工具比如(WinDBG)获取的测量值比较来间接推测。但是效果不好。

一边思考,我一边盯着WPA的界面看,突然从TimeStamp中得到了启发。首先,WPA的目前视图是关于CPU使用情况(Usage)的采样(Sampling)信息。采用是调优的两大基本手段之一(另一种是Instrumentation)。其基本原理就是每隔一段时间看一下CPU在忙什么。间隔的时间是由采样率决定的。WPA使用的默认采样率是1KHz,即每毫秒采集一个样本。时间戳就是采样的那个时刻。上面图2是按进程分组并自动折叠的,将其展开,就可以看到每个样本的时间戳信息了,其单位为秒。

96d6a20abd0f2c422a081a3972a2f734.png

展开后的每一行对应一个样本,其Weight值都大约为1ms,尝试把上图中相邻的两个时间戳相减,并不等于Weight值。这是因为在多CPU和多任务环境中,多个CPU跳来跳去,所以不能这样直接简单相减。

可这不是大问题,点击WPA界面Graph窗口的标题栏,切换到Utilization by CPU视图,就可以看每一个CPU的活动详情了。

0e45da212ebf4efacf3b0e0a5cd2d217.png

而且在这个视图中,也有Weight和Timestamp数据,拿出一组请WinDBG帮助减一下,刚好匹配。

0:005> ?? (0.804805857-0.803815460)*1000

double 0.99039700000014275

顺便说一下,在WPA中选中要复制的单元格,然后选Copy cell就可以把数据复制出来,而且让我有点惊讶的是,复制出来的数据是带单位的,Weight值的单位就是ms,比如1.099895ms。

至此,彻底把这个Weight指标“格”清楚了,它是用CPU所花时间来衡量代码的“重量”,以毫秒为单位,计算方法是使用样本的时间戳。其思想是,如果a时刻采样时看到CPU在执行函数F,那么就认为前一毫秒中CPU都在执行函数F,把a时刻与前一次采样的时刻相减的时间就算在函数F上了。如此测量,图2中加亮那一行的含义便是,BettleMania程序的测量重量为52917毫秒。看到这样的话,不做软件的肯定还是困惑,对于各位程序员同行来说,应该是可以理解的了。困惑的主要原因是指标名叫重量,单位却是毫秒。或许我们应该定义一个新的重量单位,用来测量软件,或许我们可以复用重量单位,用斤、公斤、吨之类的,那样至少说起来就顺口多了。比如,“我的手机刚才好卡,是因为昨天装了一个很重的App,测量一下,有2吨重。”

***********************************************************

正心诚意,格物致知,以人文情怀审视软件,以软件技术改变人生。

欢迎关注格友公众号

2f01729c5dc71709b2ef9ec3ee1398c8.png

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值