【问题标题】:What's the differences from inline and block compilation of SBCL?SBCL 的内联和块编译有什么区别?
【发布时间】:2020-03-19 01:42:30
【问题描述】:

几周前,SBCL 更新了 2.0.2 并带来了 Block 编译功能。我已阅读此article 以了解它是什么。

我有一个问题,(declaim (inline 'some-function)) 和 Block 编译有什么区别?块编译是由编译器自动编译的吗?

谢谢。

【问题讨论】:

    标签: compilation lisp common-lisp sbcl


    【解决方案1】:

    内联编译是一种特殊的优化技术。被调用的函数直接集成到调用函数中——通常使用其源代码——然后编译。

    这意味着内联函数可能不仅仅内联在一个函数中,而是内联在多个函数中。

    优点:调用函数的开销消失了。

    缺点:当内联函数发生更改并且我们希望此更改变得可见时,代码大小会增加并且调用函数需要重新编译。宏有同样的问题

    块编译意味着一堆代码以不同的语义约束一起编译,这使得编译器能够进行一系列新的优化。

    Common Lisp 在标准中支持块编译 单个文件。它允许文件编译器假定文件就是这样的代码块。

    Common Lisp 标准的示例:

    3.2.2.3 Semantic Constraints

    文件中对同一文件中定义的命名函数的调用引用该函数,除非该函数已声明为 notinline。如果函数在运行时单独重新定义或在同一文件中多次定义,后果是不确定的。

    这允许代码调用全局函数并且使用符号的函数单元进行调用。因此,这会为全局函数调用禁用 后期绑定 - 在此文件中和此文件中的函数。

    没有说这是如何实现的,但编译器可能只是将代码分配到某个地方,然后调用就跳转到那里。

    所以块编译的这部分是在标准中定义的,一些编译器正在这样做。

    多个文件的块编译

    如果文件编译器可以对一个文件使用块编译,那么多个文件呢?一些编译器也可以告诉文件编译器有几个文件组成了一个进行编译。 CMUCL 就是这样做的。 SBCL 是从 CMUCL 派生和简化的,直到现在还缺少它。我认为 Lucid Common Lisp(不再积极销售)也确实支持类似的东西。

    将它添加到 SBCL 可能也很有用。

    【讨论】:

    • 一个有趣的事情是编写一个block-compile-files 函数,将一堆文件合并到一个文件中,然后对其进行块编译。你会丢失关于定义来自哪里的信息(或者更确切地说,信息是错误的),但是对于那种我需要所有速度我能得到的情况,这将是一个合理的权衡。
    • @tfb:这可以通过一些准备工作:通常文件也会在编译后加载 - 这可能会造成困难......例如,宏可能需要以前加载的文件中的函数。因此,单个文件可能需要额外的 EVAL-WHEN 表单...
    • 这是考虑这个问题的错误论坛,但我想我可以说服自己,如果可以阻止将一堆文件作为一个单元编译(我认为 CMUCL 可以的方式(过去是能够吗?)那么你就不需要大量的干预了。但我实际上根本没有想过这个。
    猜你喜欢
    • 2013-10-21
    • 2017-02-11
    • 2014-08-10
    • 2018-07-11
    • 2011-03-04
    • 2010-11-26
    相关资源
    最近更新 更多