Haskell程序如何在内部编译和执行?

我很难理解Haskell(GHC)如何编译程序以及如何运行这些程序。

  • GHC是用Haskell编写的一个非平凡程序的典型例子。 但是,GHC的一些部分看起来并没有写在Haskell中,即运行时环境(在C / C--中)。 这是为什么? 性能原因? (我知道这个网站和它的朋友,但无法理解它们。)
  • 说到运行时环境:为什么编译语言需要一个? 不应该编译的程序是机器代码,而不是别的? 据我所知,运行时环境有点类似于虚拟机或字节码解释器,它处理某种形式的元代码,并基于此进行实际计算。 那么:GHC运行时间究竟做了什么,为什么它首先需要?
  • 关于FFI:C电话如何处理? 最初,我认为使用FFI生成一个单独的可执行文件,Haskell和C一起编译。 但是,我多次阅读GHC程序对C函数执行的程序调用。 这对于理解FFI在并行编程中遇到的问题尤其重要。 所以:FFI函数与普通的Haskell函数有什么不同?

  • 为了在股票硬件上编译和执行编程语言,您需要做很多事情:

  • 一个将您的源语言翻译为本地主机可执行的汇编代码的编译器
  • 用于原始语言服务(如内存管理,IO和线程管理)的支持库(也称为运行时)。 必须从较低级系统服务中利用的东西。
  • C,Java和GHC Haskell就是这样的系统的例子。 在GHC的情况下,整个架构在这里描述。 这些作品也分别进行了详细描述。

  • 编译器(用Haskell编写)将Haskell翻译为C,汇编,LLVM位码和其他格式。 它使用的策略在这里最好地描述:在股票硬件上实现懒惰的函数式语言:无Spinless Tagless G-machine。
  • 运行时服务(也称为“GHC运行时”)在几篇论文中描述:

  • 具有线程局部堆栈的多核垃圾回收器
  • 垃圾收集器服务如何工作
  • 多线程如何在GHC中工作
  • 懒惰是如何实施的
  • 运行时如何用外语调用代码

  • 我可以在运行时提供一些精确度。

    虚拟机是“一种”运行时,但不是唯一的一种。 运行时系统就是您的程序在执行过程中可能会呈现的环境(以及服务集)。 即使像C和C ++这样的非常低级的语言也有运行时系统(考虑一下malloc ......某人/某事正在为你做分配,或者甚至通过零检查进行分配)。

    一般来说,高级语言有更丰富的运行时间(意味着运行时为执行程序提供更多的服务); 那些范围从内存管理(例如垃圾收集)到反射/内省基础设施(认为ruby等等)到数组边界检查,但几乎所有的语言都有某种运行时系统(如果仅仅是操作系统)。


    1:为什么RTS没有写在Haskell中?

    因为它确实在Haskell中不能表达的底层内容。 就像Linux内核是运行C程序的系统一样,但是Linux内核的一部分是用汇编语言编写的,而不是C.

    2:为什么编译的程序需要运行时环境? 据我所知,这就像Java字节码解释器一样。

    GHCi使用几乎完全像Java字节码解释器的东西。 编译的GHC程序不会; 编译的程序是原始机器码。

    相反,Haskell RTS更像是一种微型操作系统。 它执行内存管理,它执行线程调度,它执行异常处理的某些方面,它处理事务。 每个Haskell程序都在这个迷你操作系统下运行。

    (这有点像即使编译了C程序,但它仍然是原始的机器代码,但是如果没有像Windows或Linux之类的操作系统,您仍然无法运行它。)

    例如,每当Haskell程序内存不足时,Haskell程序就会停止运行,并且垃圾收集器开始运行。 垃圾收集器试图释放一些内存,一旦有了,Haskell程序就会再次开始运行。

    每个编译好的Haskell程序都有这个垃圾收集器程序的副本,它只是Haskell RTS的一部分。 同样,多个Haskell线程可以在一个操作系统线程内部运行,因此RTS内部有一个线程调度器。 我可以继续......

    3:FFI如何处理? 我认为这些东西都是一起编译的。

    它全部被编译[或者说,链接]在一起。 如果你编写一个C程序,一个C函数可以调用另一个C函数。 当Haskell调用C函数时,它与调用该C函数的任何其他函数非常相似。 根据函数调用的作用,虽然Haskell方面有一些事情发生,但这可能会增加一些开销。

    链接地址: http://www.djcxy.com/p/7515.html

    上一篇: How are Haskell programs compiled and executed internally?

    下一篇: Why is GHC so large/big?