native Emacs Lisp

rust在PL的研究领域还挺火的

native-comp分支的bootstrap时间实在是太长了,而且大部分时间都消耗在native-comp阶 段 (ELC+ELN) 导致 make -jN 的多线程执行基本没有什么优化的空间. 趁电脑编译emacs的时 候, 分享一下如何在 Archlinux 上编译 native-comp 分支.

  1. 克隆 GCC 仓库

Archlinux 官方源里使用的 GCC 版本可以在这 里 找到.

我们用如下命令克隆对应版本的 GCC 源码

git clone -b releases/gcc-9 --depth=1000 https://github.com/gcc-mirror/gcc

为什么要用 Github 镜像? 因为 GNU 家的小水管速度只有每秒几 KB, 用 Github 镜像加上 代理后我速度达到了每秒 3M, 血与泪的教训.

  1. 获取 libgccjit PKGBUILD
git clone https://aur.archlinux.org/libgccjit.git

我们不能直接用这个 PKGBUILD, 因为已经很久没有人维护了, GCC 的版本都与 Arch repo 使用的版本脱节了, 在这里稍做修改, 指定 PKGBUILD 使用我们本地的 repo. 之所以不直 接改这个 PKGBUILD 的源, 是因为 makepkg 对于 gitrepo 只会傻乎乎的做全量克隆, 全量 克隆一个 GCC 仓库是要吐的.

diff --git a/PKGBUILD b/PKGBUILD
index 06510e7..dc35e5d 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -14,10 +14,10 @@ license=(
  'GPL3'
 )
 source=(
-   "ftp://gcc.gnu.org/pub/gcc/releases/gcc-$_gccmajor/$_gccsrc.tar.xz"
+    "libgccjit::git+file:///path/to/gcc#commit=6957d3e4eef1f4243eb23ff62aea06139ef4415a"
 )
 #  "https://sources.archlinux.org/other/gcc/gcc-8.2.1-20180831.tar.xz"
-sha512sums=('a12dff52af876aee0fd89a8d09cdc455f35ec46845e154023202392adc164848faf8ee881b59b681b696e27c69fd143a214014db4214db62f9891a1c8365c040')
+sha512sums=('SKIP')
 arch=(
  'i686'
  'x86_64'

修改完成后, 安装

makepkg -si
  1. 编译 emacs
git clone https://github.com/emacs-mirror/emacs
git checkout feature/native-comp
./autogen.sh
./configure --with-nativecomp # 重要
make
  1. 遇到的问题
  • 第一次编译时在编译完 C 代码, 开始执行 ELC+ELN 时 ld 报错找不到 crtbeginS.so 然后编译失败. 解决方案为编译前设置环境变量 export LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.1
9 个赞

gcc直接用gnu的trunk就可以,trunk是v10.0,反正和系统里的gcc版本不一样。trunk的libgccjit可能修复了一些gccemacs提到的bug。

eln编译速度慢,改一下lisp/emacs-lisp/comp.el里的comp-speed,从2改为0会快很多。否则几个小时都编译不完。

记得make -j2 以上,有几个core就几,单核编译速度太慢了。

2 个赞

谢谢,用O2优化时候,ja-dic.el这个文件编译不过去,换成O0就可以了。

顺便测了一下nbody,n取50000000时,native-comp用了642s,byte-comp用了800s左右,感觉提升还不错

在linux上,native-comp是可以直接编译过去的,不需要改代码,确实爽啊。

用native的emacs速度提升非常明显。

Apply v.s. Reduce 对照这个贴子,重新做了个图表。注意到其中cl-reduce和-reduce已经经过了native-comp,seq-reduce仍然是byte-comp。我猜测seq-reduce是用cl-defmethod定义的多态函数,生成其函数体需要手动拼接lambda,所以没法被优化。


更新:O2优化编译dash.el后,-reduce甚至比loop还要快一丢丢,实属厉害

可以看看你的emacs到底加载了哪些eln,顺便把自己用的package,有lexcal binding的elisp文件都编译了,会更爽。

今天晚上编译了一下. lsp-mode 的体验确实比以前好很多, 速度上和 vscode 差不多.

编译之后是不是改配置不需要重新编译?

只编译了package, 改配置的话不用重新编译

可以和dump一起用吗?还有想知道的就是是不是能改善multiple cursors多光标的性能?

这两个我都没用过 :sweat_smile: dump之前总是不成功, 后来就放弃了. multiplt cursors 个人不怎么用, 没留意过性能方面的问题

这个比 dump 更靠谱。

如果在速度上没有绝对的优势,dump 恐怕要凉了。

我挺在意启动速度的.

linux上,native-comp和pdump的启动速度差不多吧。都可以接受了。

看来我也要试一下了,我在archlinux上面。

就我的体验来说, native-comp已经能消除 lsp-mode 一直以来不跟手的迟滞感了. 手感和以前明显不同. 就是编译emacs时间太长了.

启动速度可以用 lazy-load 之类的技巧,但是运行时速度只有 native-comp 能改善啊

我要启动好就全部就绪,会开很多emacs,每个emacs里面都有一个或两个clojure的REPL。lazy-load对我来说没有任何意义。

我也比较在意运行速度,不过现在的情况也不算很差,毕竟cider没有lsp-mode的那种性能问题。

在arch上,我有了源码之后要怎么操作呢?(看起来有好多坑的样子)