/restrain-jit

The first and yet the only CPython compatible Python JIT, over the world.(julia backend: https://github.com/thautwarm/RestrainJIT.jl)

Primary LanguagePythonMIT LicenseMIT

restrain-jit

The first and yet the only CPython compatible Python JIT, over the world.

This comes with my talk on PyConChina 2019.

预览

p1 p2 p3

原理

procedure

  1. Python字节码

  2. 抽象机器代码定义: restrain_jit.vm.am

  3. 抽象指令: class AM的interface methods

    其中和具体指令乃至后端无关的intrinsics: restrain_jit.abs_compiler.py_apis

  4. 抽象解释代码实现

    利用抽象指令和intrinsics, 以monad方式解耦规定语义的抽象机器和具体的虚拟指令集.

  5. JuVM虚拟栈机, 前述抽象机器的一个实现.

  6. Julia栈机指令: Python 端, Julia端.

  7. Monad真好用, 全自动

  8. 栈机指令到Julia的代码生成, pattern matching真好用

  9. Julia "生成函数", 一种仅仅存在于multistage语言里, 在运行时创建无开销的函数的技巧

  10. Type level encoding技巧, 使得创建生成函数像eval一样灵活, 却比静态定义还快.

  11. Python JIT包装, 在函数中添加属性__jit__以指示已经jit过的函数

  12. PyCall.jl, 包装Pythin JIT函数的途径:

Status

  1. intrinsics还远没有实现完, 目前只实现了py_addpy_next, py_iter等.

    其实现直接简单, 很适合开PR贡献: 对照py_apis.pypy_apis.jl中给出实现.

    P.S: 如果尽可能使用C API压榨性能, 甚至可以对CPython数据结构上的操作进行加速, 见 Issue 1.

    C API使用可以参考CPython: cpython/Python/ceval.c

  2. 部分语言特性还没实现, 例如生成器, 异步, Python函数调用对关键字参数, 可变位置参数, 可变关键参数的支持.

    其中生成器的实现比较简单直接, 但异步相对来说较难(因为语义来自Python字节码).

    可变关键字参数的实现暂无高效实现.

  3. Julia对于代码生成上模拟的Push Pop行为优化不足, 这导致Restrain JIT中的for-loop很慢. 但是, 我们提供了restrain_jit.bejulia.functional模块, 导出了两个函数foreachselect, 足以用函数的方式替代控制流, 将避免性能损失.

    另外,

    • 并不复杂的的if-else不会导致性能损失.
    • 由于Julia的错误处理有开销, try语句性能较差(try语句还未经过测试)
  4. 因为是Python中文社区, 所以使用中文书写README. 轻喷.

  5. 由于依赖PyJulia的原因, 目前只能在dynamically linked的Python(例如anaconda Python, ubuntu源里的Python; Arch Linux的Python是dyn的)下使用.

    但这个限制是没有必要的, 在项目比较成熟时, 会移除PyJulia, 并使用一种前面提到的Bridging技巧, 来消除这个限制.