PHP8 的 JIT 是啥

Posted 老菜鸟的笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP8 的 JIT 是啥相关的知识,希望对你有一定的参考价值。

php8的Alpha1已经发布,关于JIT应该是大家比较关心的。扒拉了一些资料,整理了一下笔记,记录一下,以便更好的理解PHP中的JIT。

解释JIT:Just In Time, 一种编译器策略,将代码在运行时转换为依赖于体系结构的机器码,并即时执行。


关键点:

1、PHP8 的 JIT 是在 Opcache 之中提供的

2、JIT是在原来Opcache优化的优化基础之上进行优化的

3、当 JIT 按预期工作时,代码不会通过 Zend VM 执行,而是作为一组 CPU 级指令直接执行


理解起来可能有点晦涩,一步一步来看。


一、PHP代码是怎么执行的

首先我们看看PHP代码是怎么执行的:


1、读取 PHP 代码并将其解释为一组称为 Tokens 的关键字。这个过程让解释器知道各个程序都写了哪些代码。这一步称为 Lexing 或 Tokenizing 。


2、拿到 Tokens 集合以后,PHP 解释器(常用的是 PHP-FPM 和 CLI 解释器)将尝试解析他们。通过称之为 Parsing 的过程生成抽象语法树(AST)。这里 AST 是一个节点集表示要执行哪些操作。比如,「 echo 1 + 1 」实际含义是 「打印 1 + 1 的结果」 或者更详细的说 「打印一个操作,这个操作是 1 + 1」。


3、有了 AST ,可以更轻松地理解操作和优先级。将抽象语法树转换成可以被 CPU 执行的操作需要一个用于过渡的表达式 (IR),在 PHP 中我们称之为 Opcodes 。将 AST 转换为 Opcodes 的过程称为 compilation 。


4、 PHP 有一个称为 Zend VM 的引擎,该引擎能够接收一系列 Opcodes 并执行它们。执行所有 Opcodes 后, Zend VM 就会将该程序终止。


二、Opcache 扩展

它的作用是为 Opcodes 添加一个内存共享缓存层,从 AST 中提取新生成的 Opcodes 并缓存它们,以便执行时可以跳过 Lexing/Tokenizing 和 Parsing 步骤。


同样通过一张图很清晰的展示:



三、JIT如何参与解释流程

回到正题,JIT 编译会有什么效果呢?

Opcache 扩展可以更快的获取 Opcodes 将其直接转到 Zend VM,而 JIT 让它们完全不使用 Zend VM 即可运行。JIT 在运行时直接生成编译后的代码,也就是说托管代码的不再是 Zend VM,而是更为底层的 CPU。从理论上说,性能会更好。


JIT具体是怎么做的呢?


如果已编译,则 Opcodes 不会通过 Zend VM 执行。


四、结语

PHP JIT 对于使用 PHP 的网站来说提速可能并不明显,因为 JIT 在 CPU 密集型的代码上效果最好,而一般情况下,用 PHP 编写的程序都是 I/O 密集型的。简单来说就是,PHP 程序往往受限于 I/O 而不是 CPU,使 PHP 代码运行速度变慢的因素往往是它们正在执行的 I/O 操作,包括连接、读取和写入数据库、高速缓存、文件与套接字等。

关于JIT的具体配置和使用后的性能对比,后面再继续研究。


参考资料 https://thephp.website/en/issue/php-8-jit/


以上是关于PHP8 的 JIT 是啥的主要内容,如果未能解决你的问题,请参考以下文章

php8编译安装开启opcache和jit配置

支持PHP8 JIT的PHP源码加密库发布!

PHP 8 新特性之 Attributes (注解)

PHP 8的新功能展望:JIT以及其他

Swoole v4.5.9 版本发布,兼容 PHP8!

PHP 8 性能怎么样?