acovea-基于机器学习的选项搜索工具

虽然编译器有常见的O0,O2,O3优化级别,但对于高性能计算、程序调优和编译器开发人员来说,寻找更加激进的编译优化方法也是必须的。激进优化的开关就靠编译器的优化选项来控制.Open64就有大约两百多个优化选项,GCC也有100多个控制优化的选型。虽然O2,O3默认会开/关一些优化选项,但对于某个特定的应用,如何找到最优的选项组合呢?

得先说说,何为最优?,对于性能测试,跑一遍使用特定选项编译出来的程序,记录运行时间,最短的即为最优。所以在做选项搜索之前,你需要一个benchmark,用来测试运行时间。最简单的方式,就是拿一堆选项出来,先一个个的试,再两个两个的试,慢慢增加,依次抽取。遍历的方式测试这100多个选项,需要跑2^100次。

编译器的优化选项可以分为三类,开关选项,枚举选项和数值选项。开关选项,通过简单的打开和关闭来控制优化,枚举选项通过几个备选的特定值来控制优化,数值选项则是使用某个范围没的特定值来控制优化。

acovea(Analysis of Compiler Options via Evolutionary Algorithm)使用遗传算法来找到编译器中针对某个程序最优的选项组。简单来说就是自然进化的原理,把每个选项看作一个生命体的基因,好的基因让生命体更优,再通过选择,繁殖,如此往复,最终找到含有较多优良基因的生命体。对于编译出来的程序来说,就是选择能让运行时间较短的几个个体,让这些选项做交叉繁殖,生成新的选项组,再用这些选项组编译benchmark。如何安装acovea请参考acovea项目主页。

acovea提供了一个xml配置文件*.acovea,配置包括通用选项,基准选项和备选选项。通用选项就是编译benchmark必须的选项。基准选项,是作为对比基准的选项。

安装好acovea,写好配置文件,准备好benchamrk之后,就可以运行如下简单命令开始测试了。
runacovea -f CONFIG.acovea  --input BENCHMARK.c

acovea分为若干代,每一代中又包含若干生命体。每一代中的生命体通过交叉繁殖来生成下一代的生命体。对于每个生命体的一次测试,acovea会首先生成一个编译命令,包含待测试的优化选项。接着就编译,运行。记录运行时间。acovea默认40代,每代100个生命体,总共40000次测试,当然你也可以自己设置,还可以设置交叉繁殖的变异概率等等参数。测试结束后,acovea会给出一个测试报告,然后运行一遍基准测试,给出搜索出的较好选项。

其实,只要遗传算法在,acovea就可以用来测试一切有确定测试标准的搜索。比如,可以针对codesize做搜索。甚至可以挂上脚本。

经验教训:

  • 遗传算法的一大问题就是太慢,40000多次的测试,遇上时间稍长点的benchamrk,就需要一个多星期的时间。
  • 不能中断。万一测试过程出现任何问题,都要推倒重来,无法记录测试进度。
  • 结果并不理想,本博一年前曾经移植acovea用于选项搜索,但效果并不好。首先,选项太多,且相互之间可能存在干扰,会影响遗传算法的筛选结果。其次,在命令行确定的情况下,每次测试的选项数目波动小,虽然可以通过修改源码来控制选项数目,但毕竟不够灵活。最终,acovea在本博这里沦落成了简单的自动化测试工具。本博从40000多个例子里,直接挑出较好的来,最后的运行结果反而参考意义不大了。
  • 默认只能跑单个文件的benchmark。这个问题不大,改改源码,挂上脚本,啥都能干了。
  • 在多核上可以修改加速测试过程。因为acovea每一代的个体都是从上一代来的。所以每一代都可以并行测试。

相关文章:

This entry was posted in 编译技术, 编译理论实践和应用 and tagged , , . Bookmark the permalink.

5 Responses to acovea-基于机器学习的选项搜索工具

  1. Yang Shen says:

    其实,不一定用EA,可以用SA,退火算法,我当年的毕业设计就是用SA来替代EA,效果还不错,仍然可以得到较好的编译选项的优化集。用大量的时间来换取一小部分的速度还是可以考虑的。

    • erlv says:

      能否详细说说你是如何用退火算法替代EA的,在EA中,每个选项可以看作个体的基因。在SA中,虽然可以把benchmark的性能当作SA的动能。那控制参数,也就是这些选项在SA中是如何变化的呢?从完整的选项集合开始慢慢筛选吗?

      • Yang Shen says:

        参数的选择和控制是SA最开始遇到的难题,也是整个实验能否成功的核心,可以根据经验判断。但实际上我操作的时候,起始温度和迭代次数也是通过前期的一系列小的测试得出。
        另外,优化的其实选项建议从-O1 开始,而且建议根据不同的硬件和待编译优化集配置手动强制开启某些优化项。如硬件为CPU优化;待编译的文件,你则可以根据自身的特性,如有很多循环,或者多为小数等。。均有对应的优化参数。

        如果从完整集合开始优化,则结果可能不太好。也许不如自带的优化集合。

        另外,鉴于这也是随机算法的一种,所以建议,在程序中设计一个“目前最优选项”的集合,保存最优化的设置,虽然不能保证是否全局最优,但在不多的迭代后,还是很有可能需要从这里面取出你要的参数集。

        以上是我在设计过程中的一些想法,呵呵。

        • erlv says:

          也就是说这个方法,需要首先对待测试例子和CPU的特性选择一些特定的选项,比如-march, 以及手动开启一些优化选项,再选择一些可能有用的优化选项集,运行这个SA算法来选取合适的选项测试集。对吗?
          我在用acovea的时候,有一些选项需要特殊对待,不知道你当时是怎么考虑的。比如,有些需要取值的,-finline-limit=n,n可以是某个范围内的任意整数。-fira-algorithm=algorithm指定寄存器分配的算法,这个算法可以是若干算法中的一种。这种在SA中你如何处理?

          • Yang Shen says:

            我毕设的主要目的是用sa代替ea,所以我没有去关注太多的特殊选项,而是看用sa代替ea后,结果的可用行,实践证明是可以用的。
            而且我用来测试的benchmark较特殊,是以DAG为测试数据,自带multiprocessor scheduling 的算法程序。呵呵~挺有意思的。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>