有趣的编译器项目



我目前正在为研究生级别的编译器课程选择一个项目,该课程将在未来 8 周内完成。我想做一些与优化相关的事情,因为我以前在这个领域工作不多,但该领域的任何事情都是公平的。

您做过的最有趣的编译器相关项目是什么?你从中学到了最多的东西?


编辑:谢谢大家的好建议。我很抱歉这么长时间没有更新它。

我最终做的项目是在LLVM上进行简单的自动矢量化优化。LLVM具有矢量类型,但是如果没有对前端的支持,似乎没有任何方法可以利用它们。此优化将普通标量代码转换为矢量代码。

由于自动矢量化是一个相当难以实现的优化,因此我们尽可能地限制了我们的范围。首先,为了在代码中公开指令级并行性,我们寻找符合我们标准的单块循环,然后将它们展开特定次数,以便它们可以方便地矢量化。然后,我们实现了 Larsen 和 Amarasinghe 在利用多媒体指令集的超字级并行性中列出的打包算法。

即使是此优化的简化版本也非常复杂。有很多限制;例如,您不希望对循环外的变量进行矢量化,因为程序的其余部分希望它是标量。在过去的几周里,我们投入了很多时间。不过这个项目很有趣,我们学到了很多东西。

在 8 周的时间范围内,您需要小心"范围蔓延"。 不要太雄心勃勃,特别是如果这个项目包括编译器构造的其他方面(词法/解析),或者你仍在学习工具(调试器、yacc)和中间数据结构(DAG)。

也就是说,我的第一个建议是尝试一些实时变量分析。 这些算法已经非常成熟,所以你几乎只需要根据你的数据结构等进行编码。

这将允许您执行有限形式的死代码删除。 也就是说,如果检测到某个变量已声明但从未使用过,请不要为其分配空间。 如果检测到某个值已设置但从未读取,请不要生成该集。

实时变量分析也可以帮助寄存器分配,所以如果有时间,你也可以解决这个问题,并且你应该能够重用你为死代码删除构建的一些内容。

几年前,我设计了一个DSL,并为我公司生产的产品编写了编译器。DSL使用了声明性规则,事件驱动逻辑和组合继承的奇怪组合。这是一个非常有趣的项目,我学到了很多东西。

这真的激起了我对解析器和编译器的兴趣,所以我试图跟上编译器技术有趣的新发展。

关于优化,这是我去年读过的一篇有趣的文章:

http://theory.stanford.edu/~aiken/publications/papers/asplos06.pdf

在本文中,作者描述了一种自动发现窥视孔优化的技术(超越了几种流行的C++编译器后端的性能),而无需专家编写一堆特殊情况的代码。他们的技术使用无监督学习算法来发现高价值的窥视孔替代品。

阅读后,我突然想到,可以通过为算法提供"机器描述"来增强他们的方法,该描述列出了目标处理器架构支持的所有指令(及其主要效果和副作用)。然后,求解器可以更轻松地找到这些序列,而不是使用蛮力方法来查找等效的指令序列。

机器学习算法仍将使用经验观察来确定最有效的指令序列(因为缓存效应、微操作和流水线几乎需要经验计时数据),但结果等价性可以使用代数定理证明器来预测,在机器描述上操作。

在论文中,他们谈到了他们的优化器如何只能发现两个或三个指令的窥视孔替换序列(因为,否则,暴力搜索会花费太长时间并消耗太多内存)。将智能求解器放在算法中的正确位置可以使其能够处理更长的替换序列。

呜...当您完成该项目时,请告诉我!并且不要忘记在您的"致谢"部分提及我!!;-)

如果您对优化感兴趣,使用 SSE 和 MMX 指令集的循环矢量化可能会很有趣。

我认为编写我自己的简单嵌入式脚本语言是我做过的最有趣的编译器相关项目之一。它教会了我从设计到概念的过程的各个方面,并且由于我从头开始,我可以根据需要使其简单或复杂,这使我能够理解概念而不会产生很多噪音,修改已建立的项目可能会有。

考虑帮助 Shed Skin 项目,该项目将 Python 编译为 C++。 我想整个夏天,有人发出了求助电话。 确定改进编译C++的方法将为 python 程序提供惊人的优化!

http://code.google.com/p/shedskin/

对于学习编译器,端到端是最好的主意。使用简单的后端计算机,而不是x86,而是选择一些简单的计算机,如裸体MIPS。我做了针对PDP-11模拟器的本科编译器项目,这是一个很好的目标,因为它使事情变得非常简单。 多亏了一些示例代码,我们可以在大约四周内完成一个简单的命令式语言编译器。 在C!

今天,有了像ML这样强大的语言,做编译器应该容易得多。

做什么应该真正取决于你的兴趣所在。 如果是优化,找到某种简单的框架,这就是你需要关心的全部。

我认为今天最富有成效的领域是针对线程目标进行编译或即时编译。

我曾经写过一种编程语言和一个虚拟机来运行它。该语言能够与专门编写的功能接口,这些函数包含在 16 位 Windows 上的 DLL 中(这是在 OLE 自动化之前)。

从前到后做整个事情让我对语言的两端都有了很好的理解。我当时读过各种编译器书籍(比如臭名昭著的Dragon书),但直到我写了一些具体的东西,它才真正沉浸其中。现在,多年过去了,我所做的工作让我对Java VM和CLR工作有了更丰富的理解和理解。

考虑现有动态类型语言的类型推断。

除了"Dragon Book"的建议之外,我还强烈推荐Steven S. Muchnick的"Advanced Compiler Design & Implementation",它侧重于中间表示,代码生成和优化技术。

在我的本科编译器课上,我们首先从头开始为一种类似 Pascal 的语言编写了一个递归下降(自上而下)解析器:词法分析器、解析器,应有尽有。

大约在学期中期,我们转向解析器/扫描仪生成器,如lex/yacc或flex/bison。我们构建了一个编译器,它将采用我们的 Pascal 子集并将其编译为我们得到的堆栈机的汇编(堆栈机非常简单,但原理仍然相同)。

如果你对编译器感兴趣,我不能强烈推荐龙书。它旨在用于 1 个学期的本科课程,后半部分用作研究生水平的课程,并涵盖您可能希望的每一点理论和优化。连乔尔都喜欢。=)

干杯

这是另一个想法...虽然还是有点模糊:

大多数优化是在编译时完成的(JIT 编译器除外,它在运行时进行优化)。但是在链接时和安装时也有很多优化的机会。

我对一个平台的想法特别感兴趣,在这个平台上,你不会打扰链接,直到安装时。但是在安装时链接过程中,您需要采取积极的优化策略,因为您知道有关机器架构的大量详细信息,并且可以做出更微妙和更明智的优化决策。

循环检测和参数化展开应该足够困难,以使其变得有趣。不是很性感,但在 8 周内变得太性感会让你沉沦。

你可以为 IronScheme 编写一个优化器,因为它目前除了一些"内部"函数之外,可以很好地吹所有功能。 :)

其他有趣的项目可能包括:

  • 向开源的 Sun JVM 添加尾调用优化。

  • 将命名返回值优化 (NRVO) 添加到 Python 或 Ruby VM 中。

  • 为您喜欢的目标添加实时正则表达式到字节码编译(.Net 已经有了它。我很确定Java不会。

虽然编写自己的语言是一项有趣且传统的学术活动,但已经有太多实现不佳的编译器相关项目。此外,8周的时间不足以做好完整的语言实现。

如果对"与优化相关的内容"感兴趣,请选择现有语言或 VM,并针对性能、大小或两者进行优化。这将防止你不得不重新发明整个语言实现,让你专注于优化问题,将产生一个对其他人有用的产品,而不仅仅是另一个学术练习,甚至可以在找工作时有用。

我相信Parrot字节码解释器和各种.Net Iron语言解析器甚至可以从简单的优化中受益。

我在自己的教学中"很久以前"就这样做了。我不会像强调其他事情那样强调优化,比如类型推断或 JIT 或字节编码或对象格式/调试支持。

专注于优化是没有坏处的,只要你也传达出它比人们想象的要重要得多。只有在代码中才重要:

  • 调用堆栈底部的紧密循环中运行(即不显式或隐式调用函数)
  • 实际上占用了应用程序时间的很大一部分(即,如果代码很少运行,优化它不会有太大帮助)。

这只是编译器将看到的所有代码的一小部分。

编辑:可悲的是,我无法逃避使用Fortran编译器,这些编译器无情地打乱代码,使其难以调试,同时对性能产生epsilon影响。

使用启发式测试自动生成内联代码,以进行大小/速度权衡。

B::CC perl 编译器将从添加和分析类型中受益。我只是没有足够的时间。

最近时间够多了。 http://blogs.perl.org/users/rurban/2011/02/use-types.html

最新更新