大背景

在进入主题前,请先看看IBM Research以前做过的类似项目的经验:Fiorano项目。

Fiorano是IBM Research做的一次尝试,将IBM J9 JVM所使用的Testarossa(TR)编译器单独拿出来,插入到CPython运行时中为后者提供JIT编译服务。

传送门:

结果呢?当然Fiorano没有被整合到官方CPython里,不然现在大家就已经在用它了。但作为研究性项目它还是有点意思的——我觉得最重要的一点,是在一个原本没有打算与高性能JIT编译器搭配使用的runtime上,很难实现出特别有效的优化。在主流JVM上,JIT编译后的代码的速度可以轻易达到解释器速度的10x水平;而Fiorano带上了JIT却也就达到了纯解释执行的CPython的速度的1.2x~2.74x的水平范围,并没有给大家带来多少震撼…

Pyjion

开源许可证:MIT

是的,微软近期也加入了给CPython加JIT编译器的大混战。微软甚至还有一个寄身于Data Group in Azure组的Python研发组,最近开始对外宣传。

项目名是“Pyjion”,读作“pigeon”(鸽子),因为项目主力成员Dino大大想要有Python的Py音节、JIT的Ji音节的词…就找(sheng)到(zao)了这么个词出来。GJ!

说起项目主要成员之一的Dino Viehland大大,他以前是IronPython与DLR的主力开发之一,后来也参与了Python Tools for Visual Studio(PTVS)的开发。大家用Visual Studio / VS Express开发Python爽不?里面就有Dino大大的功劳。

可见他对Python那可是有深深的怨念…是真爱啊!

而Pyjion项目的另一个主要成员是Brett Cannon。他从2003年开始就是CPython的core commiter了。这也是真爱啊!

未来传送门:

言归正传,这Pyjion到底是啥呢?它是Brett和Dino做的实验产物,为了在保持完全兼容的前提下提升CPython的性能。目前基于的CPython版本是3.6 alpha 1。

项目官网的一句话说明是:"A JIT for Python based upon CoreCLR"。它目前的项目目标有三个:Add a C API to CPython for plugging in a JIT(代码) <- 最主要的目标

Develop a JIT module using CoreCLR utilizing the C API mentioned in goal #1(代码) <- 概念验证用

Develop a C++ framework

目标1很简单,就是给CPython添加一组新的C API及其实现,来为外部的JIT编译器提供接入CPython运行时的钩子。这部分目前设计和实现都很直观,看看上面的代码链接的patch就知道它是啥了——在解释器入口处添加钩子,当有JIT编译器注册进来时,一个函数在即将开始被解释执行时会先尝试JIT编译,如果成功以后就执行JIT出来的机器码;如果不成功就会把该函数标记为不可JIT编译,以后就不再尝试了。

目前这C API并不太灵活,只允许以Python函数为单元来编译,编译必须对整个函数成功,否则就得整个函数留在解释器里跑。这个API没有考虑到在函数中间跳进JIT编译的代码(On-Stack Replacement,OSR)或从JIT编译的代码中途跳回到解释器(deoptimization)之类的需求。

目标2的描述方式挺有趣的:把CoreCLR当作JIT编译器插入CPython。啥?难道为了JIT还得把整个CoreCLR都拉进来么?太可怕了!

实际上当然没那么糟糕。这个描述方式感觉是故意说得模糊一些。其实Pyjion只是要使用CoreCLR里带着的RyuJIT编译器来为CPython服务。但是当前的RyuJIT的实现依赖了CLR / CoreCLR提供的JIT编译器接口,所以要单独使用RyuJIT的话,得要把原本由CLR / CoreCLR提供的一些服务/接口给模拟出来才行。这个模拟层在Pyjion代码里就是CExecutionEngine、CorJitInfo等类。

换言之,Pyjion自身在pyjit.dll中,而它并不真的需要依赖整个CoreCLR(主体位于coreclr.dll),而只需要其中的RyuJIT(位于clrjit.dll)及其必须依赖的库(例如gcinfo),然后提供CExecutionEngine、CorJitInfo等类的实现给RyuJIT模拟出它所依赖CoreCLR的一些功能。

据说RyuJIT其实是希望未来与CLR / CoreCLR分离开,变得更独立,便于在诸如Pyjion这样的场景单独使用。目前RyuJIT与CLR确实不是由同一个组负责开发的,要分家也很合理。但未来会如何发展,外界也只能拭目以待了。

那么Pyjion是如何使用RyuJIT的呢?

它并没有实现一个RyuJIT的前端,直接把CPython字节码转换为RyuJIT的IR;而是把CPython字节码先转换为CLR的MSIL字节码,然后再让RyuJIT去把这MSIL编译成机器码,最后安装到CPython运行时里去运行。这种做法或许多少与项目组成员之前做IronPython的经历有关系,或者是与RyuJIT现在与CLR / CoreCLR的偶和有关系。

不过这里生成的MSIL只用了MSIL的指令集,而没有完全实现标准的Assembly格式;其元数据相关部分都是Pyjion用自己的数据结构模拟出来的,所以无法将生成的MSIL交给诸如ildasm之类的工具来查看。

具体的转换步骤是:CPython的解释器入口PyEval_EvalFrameEx()调用JIT编译器JitCompile()函数,传入CPython字节码。

JIT编译器入口JitCompile()创建AbstractInterpreter与PythonCompiler,调用AbstractInterpreter::compile()开始编译流程。

AbstractInterpreter类充当CPython字节码的解析器(parser),一边抽象解释CPython字节码一边调用PythonCompiler来生成MSIL。AbstractInterpreter::preprocess()先把CPython字节码里偷懒而设计的"Block"给预处理掉,把循环的跳转目标、异常处理块的边界给找出来并扁平化。可能有同学不理解“偷懒”是什么意思:Python的字节码编译器在处理循环和异常相关的控制流时,没有在编译器里处理嵌套关系,而是把“作用域栈”留到了解释器里。而正确的做法是在编译器里处理掉它,例如这样:如何对C语言的FOR语句给出一个生成中间代码的语法制导定义? - RednaxelaFX 的回答

AbstractInterpreter::interpret()遍历一遍整个CPython函数的字节码,找出基本块边界、异常处理块的边界,以及收集一些后续优化可能用到的信息。例如说它会做个很保守的逃逸分析来判断哪些值没有逃逸,后面就可以选择对它们做进一步特殊优化,例如下文提到的tagged pointer。

PythonCompiler会把每种CPython字节码的操作映射为合适的MSIL字节码序列。简单的CPython字节码可以直接映射为一条或多条MSIL字节码,而复杂的字节码则映射为Pyjion的intrinsic函数的调用。例如两个Python对象相加,会映射为对Pyjion提供的“PyJit_Add()”函数的调用,而这个函数会调用回到CPython运行时里的实现。

接下来就交给RyuJIT编译,得到编译好的机器码以及一些相关的元数据。

换句话说,Pyjion这种实现JIT编译的方式,实际的效果是把一个Python函数的字节码全部粘合到一起,去掉了解释器循环自身的开销,但是大部分复杂的操作还是调用回到CPython运行时去处理的。

要说在语义层面上的优化,Pyjion尝试了给CPython添加tagged pointer来减少小整数的内存开销,顺带提高运行性能(因为实际数据就伪装在指针里,离运算更近了)。但为了保证兼容性,tagged pointer只在被JIT编译的函数内部使用,一到return_value之类的要暴露(escape)出去的地方就还是装箱(box)回到原本的对象形态。对应的intrinsic实现在TAGGED_METHOD宏里(例如PyJit_Add_Int()就是这样来的)。

原本CPython解释器在解释执行每N条字节码指令后都会做些周期性检查,例如是否应该释放GIL来给别的线程机会执行。Pyjion把Python代码JIT编译后,这些周期性检查就安放在用户代码里的循环回跳(backedge)的地方。这跟HotSpot VM的JIT编译代码选择的放置safepoint polling的位置一样。

总体来说,Pyjion采用了一种非常保守的实现方式,很容易保证正确性,但能带来的性能提升也会非常有限。保守是否就意味着容易被接受呢?难说…搞不好会给人太多想像空间结果很失望orz

希望当前的保守设计只是一个过渡阶段。毕竟这个设计比Fiorano的做法还要保守,能带来的性能提升就更有限了。

在JIT编译之外,Pyjion还有没有向CPython注入任何其它东西呢?一点也没有。GIL、GC、监控之类的额外功能一概没碰。

IBM Python+OMR

pyjion python3.6_[新闻] CPython / 微软 Pyjion / IBM Python+OMR相关推荐

  1. pyjion python3.6_pyjion python3.6

    7天前 - pyjion-a-jit-extension-system-for-cpython)的项目,不过这个项目已经停止...演示中用的是Python 3.6.6: wget https: //g ...

  2. 微软、IBM们的中国研究院是怎样一步步“躺平”的?

    来源: 脑极体 IBM中国研究院关闭的消息,又让大家想起了曾经甲骨文.微软.Adobe等外企研究机构离华的新闻.从上世纪末本世纪初来华,十多年情缘突然宣告分手,固然是遗憾的,也更令人好奇背后的原因. ...

  3. 微软、IBM对垒大数据

    6月20日消息,据国外媒体报道,我们生活在一个数据的时代,这是毋庸置疑的.许多人全天"吊在网上",互联网公司收集的数据量是令人吃惊的.但是,收集数据只是第一步,也是较为简单的一步. ...

  4. 微软彻底拥抱 Python!

    [CSDN 编者按]一直以来,C# 可以说是微软在编程语言方面最为显著的一大标签,甚至于知乎上都有「微软的所有程序员都用 C# 吗?」的提问.但时至今日,微软正在逐步地拥抱 Java.JavaScri ...

  5. python3哪个版本稳定-不要再纠结Python哪个版本好,2020年用Python3就对了

    2020年用Python3就对了!Python 3比Python 2慢吗?哪一个版本的Python 3最快?不要再纠结Python哪个版本好!还有什么其他措施可以提高速度?哪个版本的Python最快? ...

  6. 微软独家采访Python之父! 大爆料13个问题,快来看看龟叔的怎么说!

    公众号后台回复"图书",了解更多号主新书内容作者:菜鸟哥来源:菜鸟学Python 作为Python之父的龟叔,从加入微软到现在,已经有半年的时间了.微软也是在龟叔入职的半年之际,独 ...

  7. 微软400集python课程-最强福利——来自微软的Python学习教程(开发指南)

    各位小伙伴们,大家有多久没有发现柳猫这么勤奋的更新啦~ 今天给小伙伴们带来微软的官方福利,你没看错,就是来自微软的官方Python学习教程(开发指南)~ 之前微软上线过一套 Python 教程< ...

  8. centos7 python3.6升级到3.7_Centos7下把python 2.7升级到python 3.6(升级过程遇到的一些相关问题)...

    Centos 7 默认安装的Python 的版本是2.7的,现在不少人用的是3.x上的版本,故而需要了解下如何从Python2.7升级到Python 3.6. 在虚拟机安装时,网络不通会先遇到一个错误 ...

  9. python2和python3如何共存,如何安装多版本python python2和python3共存以及pip共存

    Python的版本是挺折腾人的,本着简单实用的原则我介绍一下我是如何安装多版本Python的. 环境:windows10(64位) Python版本:2.7.13和3.5.2 1.安装Python2. ...

最新文章

  1. 【转】POJ 2104 K-th Number(2)
  2. C++ 标准库中的异常
  3. ST表 (模板) 洛谷3865
  4. 敏捷个人2012.7月份线下活动报道:珠海 时中法、深圳 敏捷个人理念
  5. 科学计算:Python VS. MATLAB(4)----图形系统简介
  6. 【机器学习基础】数学推导+纯Python实现机器学习算法30:系列总结与感悟
  7. php框架控制器是什么意思,控制器定义
  8. marked Options
  9. python爬取糗事百科
  10. 当集合a为空集时a的取值范围_高中数学必修一第一章集合分节练习和章末测试题含答案[1] 2...
  11. ubuntu下的eclipse 3.3初用aptana报SWT错误
  12. 蓝牙鼠标windows linux,Ubuntu下使用蓝牙无线鼠标[图]
  13. 关于interface
  14. 如何用C++做一个简单的QQ整人程序
  15. 通达信版弘历软件指标_通达信获利分析仿弘历软件的六彩神龙指标公式
  16. [Linux驱动炼成记] 06-博通WIFI模组AP6212配置
  17. 1032: 员工薪水 Python
  18. LeetCode:934. Shortest Bridge - Python
  19. 视觉欺骗:你绝不会相信A和B颜色相同!
  20. 基于TensorFlow的开源JS库的网页前端人物动作捕捉的实现

热门文章

  1. 一键打造全栈式小程序开发者!
  2. 【快报】程序员,别再埋头学Python了!
  3. 低代码再掀炒作热潮?
  4. 什么是 DNS 劫持、投毒、解析?看这文就懂了!
  5. 如何拯救美团的“中年危机”?
  6. @程序员,不会 Debug 还做什么开发?
  7. 大话云上“分布式实践”,理解 B、A、C 并不难!
  8. 一文看懂 BDTC 2018:探秘大数据新应用(附 PPT 下载)
  9. Android 开发者们,如何使用 Python 来扩展 adb 命令?
  10. 台式电脑计算机能创建新磁盘吗,解决方案:如何添加硬盘以扩展台式计算机上的存储空间|如何对新添加的硬盘进行分区...