在Haskell中进行编程时(尤其是在解决Project Euler问题时,其中次优解决方案往往会强调CPU或内存需求)我经常感到困惑,为什么程序的行为方式如此。我看一下配置文件,尝试引入一些严格性,选择另一种数据结构,......但主要是在黑暗中摸索,因为我缺乏良好的直觉。
此外,虽然我知道Lisp,Prolog和命令式语言是如何实现的,但我不知道如何实现一种懒惰的语言。我也有点好奇。
因此,我想了解更多关于从程序源到执行模型的整个链。
我想知道的事情:
应用了哪些典型优化?
当有多个评估候选者时,执行顺序是什么(虽然我知道它是从所需的输出驱动的,但是在首先评估A然后是B或者首先评估B之间可能仍存在很大的性能差异你根本不需要A)
thunks如何代表?
如何使用堆栈和堆?
什么是CAF? (分析表明有时热点在那里,但我没有线索)
答案 0 :(得分:55)
关于GHC系统架构和方法的大部分技术信息都在他们的wiki中。我将链接到关键部分,以及一些人们可能不知道的相关论文。
应用了哪些典型优化?
关于此的主要文件是:A transformation-based optimiser for Haskell, SL Peyton Jones和A Santos,1998,描述了模型GHC使用类似保留变换(重构)核心Haskell类语言来改善时间和内存使用。这个过程称为“简化”。
在Haskell编译器中完成的典型事情包括:
有时候:
上述论文是开始理解大多数优化的关键所在。一些较简单的内容在早期的书中提供, Implementing Functional Languages ,Simon Peyton Jones和David Lester。
有多个评估候选人时的执行顺序是什么
假设您使用的是单处理器,那么答案就是“编译器根据启发式选择静态选择的一些顺序,以及程序的需求模式”。如果你通过sparks使用推测评估,那么“一些非确定性的,无序的执行模式”。
通常,要查看执行顺序是什么,请查看核心,例如, ghc-core工具。introduction to Core。 the layout of heap objects是关于优化的RWH章节。
thunks如何代表?
Thunks表示为带有代码指针的堆分配数据。
见how thunks are represented。 具体来说,请参阅the design of the Spineless Tagless G-machine。
如何使用堆栈和堆?
由thread object has a stack确定,具体而言,自该论文发布以来进行了许多修改。广泛地说,执行模型:
要深入了解堆栈使用模型,请参阅treated specially by the garbage collector。
什么是CAF?
“不变的申请表”。例如。在程序执行期间分配的程序中的顶级常量。由于它们是静态分配的,因此必须为The GHC Commentary。
参考和进一步阅读:
答案 1 :(得分:9)
这可能不是你在介绍性文字方面的想法,但Edward Yang有一系列博客文章讨论Haskell堆,如何实施thunk等等。
这既有插图也有娱乐性,而不需要为Haskell的新手深入细节。该系列涵盖了您的许多问题:
在更技术层面上,有许多论文(与其他内容一致)涵盖了您想要了解的部分内容: