老莫

靠编译器能否有效提升多核处理器能效?

0
阅读(23213)

最近小G同学做了个高能效并行计算方面的presentation,我帮她搞了搞。其中有一篇讲利用编译器信息来为多核处理器分配DVFS,我觉得写得还是很不错的,于是花了很多时间对这篇文献进行了总结。还写了N多自己的看法。

未曾想到做presentation的时候,复旦的某大佬将这篇文章说得是一文不值。其核心意思就是编译器所掌握的信息是极其有限的,等真正run起来以后,实际情况是难以预料的。所以根本不可能靠编译器提升多高的处理器能效。

小G同学转述了这个大佬的话以后,搞得我异常郁闷,还和小G同学小发了一会脾气。后来想想挺对不起她的,毕竟这是哪个大佬说的,而不是她说的。

在并行计算的时候什么情况下能效最高呢?当然是大家任务差不多同时做完,不存在中断、间隔和停顿的时候。这样就没有额外的时间和能量浪费在等待上面。 因而根据编译出来的结果,合理的分配每个核的任务以及这个核的运行电压和频率。靠编译器编译器是否能有效提升多核能效呢?说到底是看编译器是否能有效地通过掌握的信息预测到处理器运作的状态。

对于处理器的运行状态而言,确实是在run起来以后受很多因素的影响。但是处理器run的程序也是有很大区别的,对于run不同的程序时处理器的状态是否可以通过编译器来预测是有很大不同的。其实计算机程序就我看来可以大致的分为两类:请求-响应类和流计算类。请求-响应类计算,是通用计算中较为常见的。我现在就在做着请求-响应式的计算。我敲一个字,电脑的显示器上响应一个字出来。我什么时候敲,敲的什么,敲的速度有多快,这个光靠分析程序是很难获得的。因而这类应用,光靠编译器确实是很难的。但对于流计算而言,例如视频编解码、图像处理器、信号分析等多媒体运算,其具备以下特点:

1、运算规整,通常是各类矩阵运算。数据的处理过程通常可以用若干的循环嵌套表示。

2、数据预测性好,其数据类型基本固定,而且其数据耦合比较紧密,通常以连续储存的形式存放在一个连续的数据段中。从而在一定程度上降低了cache缺失的不可预知性。

3、运算过程延续性好,一旦启动之后将持续一段时间长期处理一类任务

4、处理过程单一,通常可以用比较抽象的任务依赖图或者循环依赖图表示

因此,在分析这类运算时,可以非常容易的分析出其核心循环所在。通过分析核心循环中的操作数, 可以估计出并行化之后每个核上面任务的总操作数。如果再想预测的准一点,可以考虑加入一点分支预测和概率统计的模型进去,其实可以分析到足够好的程度极大的提高能效。

最终的结论是,compiler这个东西虽然知道的信息确实有限,但是对于很多特征明显的、运算规则的计算任务而言,还是足够能够预知整个程序run起来以后的状态的。

不过由于流计算这类计算并行程度实在有限(如对于某一个视频播放程序可以认为是一个流计算,总共也要不了几个核来处理),而不同的流计算之间其实属于并发而非并行了。目前真正大规模并行的计算如搜索、社交网络等,很多时候确实无法以流计算的方法来将其并行起来。所以,这篇论文的局限性是明显的,但是并非说别人是瞎扯的。

之后我们将对这篇论文足够多的分析,汲取其核心思想用于我们的论文中。