关于 GHC 实施的好的介绍性文字?

Posted

技术标签:

【中文标题】关于 GHC 实施的好的介绍性文字?【英文标题】:Good introductory text about GHC implementation? 【发布时间】:2011-08-28 05:43:17 【问题描述】:

在 Haskell 中编程时(尤其是在解决 Project Euler 问题时,次优的解决方案往往会对 CPU 或内存需求造成压力),我经常对为什么程序的行为方式感到困惑。我查看配置文件,尝试引入一些严格性,选择另一种数据结构,......但大多是在黑暗中摸索,因为我缺乏良好的直觉。

另外,虽然我知道 Lisp、Prolog 和命令式语言的典型实现方式,但我不知道如何实现惰性语言。我也有点好奇。

因此,我想更多地了解从程序源到执行模型的整个链条。

我想知道的事情:

应用了哪些典型优化?

当有多个评估候选者时,执行顺序是什么(虽然我知道它是由所需的输出驱动的,但先评估 A 再评估 B 或先评估 B 以检测可能仍然存在很大的性能差异你根本不需要A)

thunk 是如何表示的?

栈和堆是如何使用的?

什么是 CAF? (分析有时表明热点在那里,但我不知道)

【问题讨论】:

不完全是我所说的介绍性,但SPJ's book on the implementation of functional languages 是一本好书。 Uuhh.. 对我来说,这是对 GHC 研究人员发表的大量论文的深入挖掘。如果您对数据表示感兴趣,Edward Z. Yang 的 series of blog posts 可能对您很感兴趣。 相关:How does a Haskell compiler works? 这是我一直想问的问题。熟悉论文是一个好的开始。它们是可读的。你可能对垃圾收集感兴趣,因为它们揭示了大部分底层结构(闭包块是如何实现的)。对于不同的编译器通道,我不知道。 关于第二项,如果A真的只用于B的某些值,那么A将在B之后评估或根本不评估,因为从未被评估过强迫?除非有其他东西造成了不必要的严格性,在这种情况下,即使 A 无论如何都不需要,也可能会被评估。 【参考方案1】:

这可能不是您在介绍性文本中所想的,但 Edward Yang 有一系列博客文章正在讨论 Haskell 堆、如何实现 thunk 等。

这很有趣,既有插图,也有对 Haskell 新手的解释,无需深入研究太多细节。该系列涵盖了您的许多问题:

The Haskell heap and how thunks are stored - 系列中的第一篇文章 Bindings and CAFs How the IO monad gets translated into primitives

在更技术层面上,有许多论文涵盖(与其他事物一致),您想知道的部分内容。:

A paper by SPJ, Simon Marlow et al on GC in Haskell - 我还没读过它,但由于 GC 通常代表了 Haskell 所做工作的一个很好的部分,它应该提供洞察力。 The Haskell 2010 report - 我相信你一定听说过这个,但不链接到太好了。可以在某些地方进行枯燥的阅读,但这是了解 Haskell 为何如此的最佳方式之一,至少是我读过的部分。 A history of Haskell - 比名称所暗示的更具技术性,并为 Haskell 的设计和设计背后的决策提供了一些非常有趣的观点。看完Haskell的实现会让你不由得更加了解。

【讨论】:

【参考方案2】:

有关 GHC 系统的架构和方法的大部分技术信息都在他们的 wiki 中。我将链接到关键部分,以及一些人们可能不知道的相关论文。

应用了哪些典型优化?

这方面的关键论文是:A transformation-based optimiser for Haskell, SL Peyton Jones 和 A Santos,1998 年,描述了 GHC 使用的模型,该模型通过应用核心类 Haskell 语言的类型保留转换(重构)来改善时间和内存使用。这个过程称为“简化”。

在 Haskell 编译器中完成的典型事情包括:

内联; Beta 减少; 死代码消除; 条件转换:case-of-case、case elimination。 拆箱; 构造产品退货; 完全惰性转换; 专业化; Eta 扩展; Lambda 提升; 严格性分析。

有时:

静态参数转换; 构建/折叠或流融合; 通用子表达式消除; 构造函数专业化。

上述论文是开始理解大部分优化的关键所在。较早的书Implementing Functional Languages、Simon Peyton Jones 和 David Lester 中给出了一些更简单的方法。

当有多个候选评估时执行顺序是什么

假设您使用的是单处理器,那么答案是“编译器根据启发式方法和程序的需求模式静态选择的某种顺序”。如果您通过 sparks 使用推测性评估,那么“一些不确定的、无序的执行模式”。

一般来说,要查看执行顺序是什么,请查看核心,例如ghc-core 工具。 introduction to Core 在 RWH 优化章节中。

thunk 是如何表示的?

thunk 表示为带有代码指针的堆分配数据。

见the layout of heap objects。 具体见how thunks are represented。

栈和堆是如何使用的?

由the design of the Spineless Tagless G-machine 确定,具体而言,自该论文发布以来进行了许多修改。概括地说,执行模型:

(装箱的)对象在全局堆上分配; 每个thread object has a stack,由与堆对象布局相同的帧组成; 进行函数调用时,将值压入堆栈并跳转到函数; 如果代码需要分配,例如构造函数,该数据被放置在堆上。

要深入了解堆栈使用模型,请参阅"Push/Enter versus Eval/Apply"。

什么是 CAF?

“恒定应用形式”。例如。为程序执行的整个生命周期分配的程序中的***常量。因为它们是静态分配的,所以它们必须是treated specially by the garbage collector。


参考资料和延伸阅读

The GHC Commentary The Spinless Tagless G-machine Compilation via Transformation Push/Enter vs Eval/Apply Unboxed Values as First-Class Citizens Secrets of the Inliner Runtime Support for Multicore Haskell

【讨论】:

老实说,我不知道您是如何抽出时间来提供这么多详细、图解、参考充分的答案,但我很高兴您这样做 :) 大部分内容都缓存在我多年读研究生的脑海中 :-)

以上是关于关于 GHC 实施的好的介绍性文字?的主要内容,如果未能解决你的问题,请参考以下文章

图片文字转word文档的巧妙方法

ScopedTypeVariables 和 RankNTypes 与 GHC.TypeLits

C++/Cli 文字数组初始化

关于client浏览器界面文字内容溢出用省略号表示方法

mapbox.gl文字标注算法基本介绍

鸟哥的linux私房菜:基础学习篇 (第四版)pdf文字版 30MB完整高清版下载