JIT的基本概念
JIT(Just-In-Time Compilation,即时编译)runtime编译,php的opcache.jit在程序运行时将字节码转换为机器码,以提高代码的执行效率。
jit在软件领域里面不是一个新名词,例如lua脚本,jit对其性能的提升得到了充分验证。
经过php5.6时代开始长年的性能争论, 和zend核心开发者的大力介入, php8.0版引入了jit,同样是为了提升计算密集型任务中的性能, 设法让php以简单易上手的形象, 能够跻身cpu(中等)密集型操作、应付相对复杂的计算。
zend从8.0到现在一直在优化jit, 据说这个后起之秀已经逐渐接近了Java8和Node.js v8。
问题: swoole开jit有没有用?
江湖讹传swoole是常驻内存的, 没必要开jit。实际非也、非也。
swoole+jit配置详解
php.ini改以下的内容开jit:
zend_extension="opcache.so" opcache.enable=1 opcache.enable_cli=1 opcache.jit_buffer_size=128M
注意这一项, 在php 8.5提高这个配置的值, 可成倍提升密集运算性能。
opcache.jit=1225
设置 JIT 优化等级,1225就很好,传送门:https://www.php.net/manual/zh/opcache.configuration.php#ini.opcache.jit-buffer-size
php.ini当中opcache.jit等号后面的配置解释
opcache.jit的值是一个字符串,或4字节数字,每个字节表示一项设置, 如果你写的是字符串值:
disable:完全禁用,无法在运行时启用
off:禁用,但可以在运行时启用
tracing/on:使用追踪 JIT。默认启用并推荐给大部分用户
function:使用函数 JIT
"tracing" 模式对应 CRTO = 1254,"function" 模式对应 CRTO = 1205。
如果你写的是数字:
针对高级用法,此选项接受 4 位整数 CRTO,其中的位分别是:
C(特定 CPU 优化 flag)
0:禁用特定 CPU 优化
1:如果 CPU 支持则启用 AVX
R(寄存器分配)
0:不执行寄存器分配
1:执行局部域寄存器分配
2:执行全局寄存器分配
T(触发)
0: 在脚本加载时编译所有函数
1: 在第一次执行时编译函数
2:第一次请求时分析函数,然后编译最热门函数
3:动态分析和编译热门函数
4:目前未使用
5:使用追踪 JIT。动态分析和为热门代码段编译追踪
O(优化级别)
0:关闭 JIT 优化
1:最小 JIT(调用标准 VM 处理程序)
2:内联 VM 处理程序
3:使用类型推断
4:使用调用图
5:优化整个脚本
在 Swoole 协程下,第三项 T(触发) 的等级必须为大于或等于2,否则swoole Runtime Hook不会生效。
啰嗦了一大堆, 你不如听我的, 直接写1225
opcache.jit=1225
jit测试结果
测试结果传送门:https://php.watch/articles/jit-in-depth
“此测试是基于 PHP 8.0,当前的 8.3 版本相比又有了较大的性能提升”