编程是一门实践技能,积极动手实验常有意外的收获

这是自己这一周的一点小体会。

说来惭愧,这周以来一直在琢磨工程当中某个函数的优化,任务描述当中是说此函数在执行过程当中出现了Pipeline Stall的情形,并且消耗的cycles数也位居前列。读它千百遍下来却没有一个好的思路入手。从整个函数的逻辑上去看,其中的的确确多次调用了其他的函数,并且做了不少的数据计算。但是真实的业务需求就需要它做那些操作,看起来由此产生的heavy cost自然也是顺理成章的了。

思来想去实在没有办法,想想即便无法优化也得把数据摆出来,好让大家一起商量着。所以便开始动手对其中的调用进行打点测量。可喜的是,在第一轮抓取到数据之后就现这个数据与想象当中的不一样,之后一步一步的深入挖掘更多数据-->分析偏差的地方-->出方案优化-->重新测量-->解决测量当中的疑惑,就这样一步一步的竟然很快把问题给解决掉了。在这个过程当中发现:

  • 之前自认为最耗费DSP性能的部分实际上在测试当中并没有执行到(依赖特性未使能)

  • 该函数调用消耗掉的好几百cycle主要开销由“该函数的调用”和“其中的一个数据获取操作”引起,而后者当是引起cache miss的原因。这个数据操作动作实在是太不起眼了,因为在代码当中被广泛使用到

最后解决掉这个任务的方案很简单,只需要加一个if判断语句即可以将cycles数降到之前的六分之一。从头梳理一下整个问题的解决过程,有一个有趣的结论,这也是本篇笔记的主题:

  1. 反复阅读代码,推敲,没有发现可以优化的地方;
  2. 先为函数各部分做bench mark,分析数据发现之前的理解有偏差;
  3. 继续测试,并逐步添加优化修改,再测试,找到主要原因所在;
  4. 最终优化,再次测试。

考虑在如上四个步骤的精力分配,在过程1中花的时间是最多的,却是一段“不舒服的时光”。而整个问题解决的转机出现在动手测量、分析之后。在这里我想表达的是在做事情的时候尽量不要凭空猜测,如果有条件就动手去实验,这样做往往收获很大。当然,在这里的“做事情”指的是以各种目的之下的编写代码(开发特性,重构,性能攻关等等)。

无独有偶,早上在读到《重构——改善既有代码的设计》第二章的时候,其中Ron Jeffeies的一则“劳而无获”的小故事中提到一个教训:

哪怕你完全了解系统,也请实际度量它的性能,不要臆测。臆测会让你学到一些东西,但十有八九你是错的。

这让当时的我突然惊叫到,这太TM对了!我也是这么想的!(喜泪狂飙啊~)更有趣的是,本章结尾时Rich Garzaniti有关“优化一个薪资系统”的故事当中,作者在故事结束时也总结到:

在Jim提供工具使我们得以在实际操作中度量系统性能之前,我们也猜测过问题所在。但如果只靠猜测,我们需要很长的时间才能试出真正的解法。真实度量指出了一个完全不同的方向,并大大加快了我们的进度。

再看到这里的时候又有一种莫名的兴奋感,觉得实在是说得太好了。这两个故事都是作者引用在书当中的,里面讲的虽然是重构相关的故事,但是总结的经验却似乎是专门为此情此景而准备的:别一直愣着,动手啊!

你可能感兴趣的:(编程)