PHP 8在PHP的内核中添加了JIT编译器,可以极大地提高性能。关于对实际Web应用程序的实际影响,需要做一些旁注,这就是为什么我对JIT的性能进行一些基准测试的原因(我也在脚注中列出了所有相关参考资料)。
我还想写一篇有关如何设置JIT的博客文章,因为有很多事情要讨论。
老实说,设置JIT是我见过的配置PHP扩展最混乱的方法之一。幸运的是,有一些可用的配置速记,因此更容易设置。深入了解JIT配置仍然是一件好事,所以在这里说明。
首先,仅在启用opcache的情况下,JIT才有效,这是大多数PHP安装的默认设置,但您应确保opcache.enable
在php.ini
文件中将其设置为1 。通过在php.ini
中指定opcache.jit_buffer_size
来启用JIT本身。
请注意,如果您通过命令行运行PHP,则还可以通过-d
标志传递这些选项,而不是将它们添加到php.ini
:
php -dopcache.enable=1 -dopcache.jit_buffer_size=100M
如果不包含此伪指令,那么默认值将设置为0,并且JIT将不会运行。如果要在CLI脚本中测试JIT,则需要使用opcache.enable_cli
来启用opcache:
php -dopcache.enable_cli=1 -dopcache.jit_buffer_size=100M
opcache.enable
和opcache.enable_cli
之间的区别是,如果要运行,例如内置的PHP服务器则应该使用前者。如果您实际上正在运行CLI脚本,则需要opcache.enable_cli
。
在继续之前,让我们确保JIT确实有效,创建一个可通过浏览器或CLI访问的PHP脚本(取决于您测试JIT的位置),并查看以下输出opcache_get_status()
:
var_dump(opcache_get_status()['jit']);
输出应该是这样的:
array:7 [
"enabled" => true
"on" => true
"kind" => 5
"opt_level" => 4
"opt_flags" => 6
"buffer_size" => 4080
"buffer_free" => 0
]
如果enabled
和on
是正确的,那您就对了!
接下来,有几种配置JIT的方法(这是我们讨论配置混乱的地方)。您可以配置JIT运行的时间,应该尝试优化的数量等等。所有这些选项都使用一个配置条目配置:opcache.jit
! 它可能看起来像这样:
opcache.enable=1
opcache.jit=1255
现在,这个数字是什么意思?该RFC列出他们每项的意义。请注意:这不是位掩码,每个数字仅表示一个配置选项。RFC列出了以下选项:
#O-优化级别
0 | 不要JIT |
1个 | 最小JIT(调用标准VM处理程序) |
2 | 选择性VM处理程序内联 |
3 | 基于单个函数的静态类型推断的优化JIT |
4 | 基于静态类型推断和调用树的优化JIT |
5 | 基于静态类型推断和内部过程分析的优化JIT |
#T — JIT触发器
0 | JIT第一次脚本加载时的所有函数 |
1个 | 首次执行时JIT函数 |
2 | 在第一个请求时进行概要分析,并在第二个请求时编译热函数 |
3 | 动态分析并编译热函数 |
4 | 在文档注释中使用@jit标记编译函数 |
5 | 跟踪JIT |
#R-寄存器分配
0 | 不执行寄存器分配 |
1个 | 使用本地线性扫描寄存器分配器 |
2 | 使用全局线性扫描寄存器分配器 |
#C — CPU特定的优化标志
0 | 没有 |
1个 | 启用AVX指令生成 |
一个小问题:RFC以相反的顺序列出了这些选项,因此第一个数字代表C
值,第二个数字代表值R
,依此类推。为什么我不理解为什么根本没有添加四个配置条目,可能是为了更快地配置JIT?
无论如何,内部人员建议将1255
作为最佳默认设置,它将最大程度地jitting,使用跟踪JIT,使用全局线性扫描寄存器分配器(无论如何)并启用AVX指令生成。
因此,您的ini设置(或-d
标志)应具有以下值:
opcache.enable=1
opcache.jit_buffer_size=100M
opcache.jit=1255
请记住,这opcache.jit
是可选的。如果忽略该属性,则JIT将使用默认值。
您问哪个默认值?那会是opcache.jit=tracing
。
等等,那不是我们之前看到的奇怪的类似于位掩码的结构吗?没错:在原始RFC通过之后,内部人员意识到,类似于位掩码的选项并不是所有的用户友好选项,因此他们添加了两个别名,这些别名被转换为底层的位掩码。有opcache.jit=tracing
和opcache.jit=function
。
两者之间的区别在于,函数JIT仅会尝试在单个函数的范围内优化代码,而跟踪JIT可以查看整个堆栈跟踪以识别和优化热代码。内部人员建议使用跟踪JIT,因为它几乎总是可以提供最佳结果。您可以在我完成的基准测试中了解这些结果。
因此,您实际上需要设置的唯一选项以启用最佳配置来启用JIT是 opcache.jit_buffer_size
,但是如果您要明确一点,列出opcache.jit
并不是一个坏主意:
opcache.enable=1
opcache.jit_buffer_size=100M
opcache.jit=tracing
原文 https://stitcher.io/blog/php-8-jit-setup 原创翻译:转载请注明来自lenix的博客,地址https://blog.p2hp.com/archives/7577