PHP8新特性之JIT简介

Wesley13
• 阅读 304

PHP8 alpha1已经在昨天发布,相信关于JIT是大家最关心的,它到底怎么用,有什么要注意的,以及性能提升到底咋样?

首先,我们来看一张图:

左图是PHP8之前的Opcache流程示意图, 右图是PHP8中的Opcache示意图, 可以看出几个关键点:

  • PHP8的JIT是在Opcache之中提供的
  • 目前PHP8只支持x86架构的CPU
  • JIT是在原来Opcache优化的优化基础之上进行优化的,不是替代

事实上JIT共用了很多原来Opcache做优化的基础数据结构,比如data flow graph, call graph, SSA等,关于这部分,后续如果有时间,可以单独在写一个文章来介绍,今天就只是着重在使用层面。

下载安装好以后,除掉原有的opcache配置以外,对于JIT我们需要添加如下配置到php.ini:

opcache.jit=1205
opcache.jit_buffer_size=64M

opcache.jit这个配置看起来稍微有点复杂,我来解释下, 这个配置由4个独立的数字组成,从左到右分别是(请注意,这个是基于目前alpha1的版本设置,一些配置可能会随着后续版本做微调):

  • 是否在生成机器码点时候使用AVX指令, 需要CPU支持:

    0: 不使用
    1: 使用
    
  • 寄存器分配策略:

    0: 不使用寄存器分配
    1: 局部(block)域分配
    2: 全局(function)域分配
    
  • JIT触发策略:

    0: PHP脚本载入的时候就JIT
    1: 当函数第一次被执行时JIT
    2: 在一次运行后,JIT调用次数最多的百分之(opcache.prof_threshold * 100)的函数
    3: 当函数/方法执行超过N(N和opcache.jit_hot_func相关)次以后JIT
    4: 当函数方法的注释中含有@jit的时候对它进行JIT
    5: 当一个Trace执行超过N次(和opcache.jit_hot_loop, jit_hot_return等有关)以后JIT
    
  • JIT优化策略,数值越大优化力度越大:

    0: 不JIT
    1: 做opline之间的跳转部分的JIT
    2: 内敛opcode handler调用
    3: 基于类型推断做函数级别的JIT
    4: 基于类型推断,过程调用图做函数级别JIT
    5: 基于类型推断,过程调用图做脚本级别的JIT
    

基于此,我们可以大概得到如下几个结论:

  • 尽量使用12x5型的配置,此时应该是效果最优的
  • 对于x, 如果是脚本级别的,推荐使用0, 如果是Web服务型的,可以根据测试结果选择3或5
  • @jit的形式,在有了attributes以后,可能变为<>

现在,我们来测试下启用和不启用JIT的时候,Zend/bench.php的差异,首先是不启用(php -d opcache.jit_buffer_size=0 Zend/bench.php):

simple             0.008
simplecall         0.004
simpleucall        0.004
simpleudcall       0.004
mandel             0.035
mandel2            0.055
ackermann(7)       0.020
ary(50000)         0.004
ary2(50000)        0.003
ary3(2000)         0.048
fibo(30)           0.084
hash1(50000)       0.013
hash2(500)         0.010
heapsort(20000)    0.027
matrix(20)         0.026
nestedloop(12)     0.023
sieve(30)          0.013
strcat(200000)     0.006
------------------------
Total              0.387

根据上面的介绍,我们选择opcache.jit=1205, 因为bench.php是脚本(php -d opcache.jit_buffer_size=64M -d opcache.jit=1205 Zend/bench.php):

simple             0.002
simplecall         0.001
simpleucall        0.001
simpleudcall       0.001
mandel             0.010
mandel2            0.011
ackermann(7)       0.010
ary(50000)         0.003
ary2(50000)        0.002
ary3(2000)         0.018
fibo(30)           0.031
hash1(50000)       0.011
hash2(500)         0.008
heapsort(20000)    0.014
matrix(20)         0.015
nestedloop(12)     0.011
sieve(30)          0.005
strcat(200000)     0.004
------------------------
Total              0.157

可见,对于Zend/bench.php, 相比不开启JIT,开启了以后,耗时降低将近60%,性能提升将近2倍

对于大家研究学习来说,可以通过opcache.jit_debug来观测JIT后生成的汇编结果,比如对于:

function simple() {
  $a = 0;
  for ($i = 0; $i < 1000000; $i++)
    $a++;
}

我们通过php -d opcache.jit=1205 -dopcache.jit_debug=0x01 可以看到:

JIT$simple: ; (/tmp/1.php)
    sub $0x10, %rsp
    xor %rdx, %rdx
    jmp .L2
.L1:
    add $0x1, %rdx
.L2:
    cmp $0x0, EG(vm_interrupt)
    jnz .L4
    cmp $0xf4240, %rdx
    jl .L1
    mov 0x10(%r14), %rcx
    test %rcx, %rcx
    jz .L3
    mov $0x1, 0x8(%rcx)
.L3:
    mov 0x30(%r14), %rax
    mov %rax, EG(current_execute_data)
    mov 0x28(%r14), %edi
    test $0x9e0000, %edi
    jnz JIT$$leave_function
    mov %r14, EG(vm_stack_top)
    mov 0x30(%r14), %r14
    cmp $0x0, EG(exception)
    mov (%r14), %r15
    jnz JIT$$leave_throw
    add $0x20, %r15
    add $0x10, %rsp
    jmp (%r15)
.L4:
    mov $0x45543818, %r15
    jmp JIT$$interrupt_handler

而如果我们采用opcache.jit=1201, 我们可以得到如下结果:

JIT$simple: ; (/tmp/1.php)
    sub $0x10, %rsp
    call ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER
    add $0x40, %r15
    jmp .L2
.L1:
    call ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER
    cmp $0x0, EG(exception)
    jnz JIT$$exception_handler
.L2:
    cmp $0x0, EG(vm_interrupt)
    jnz JIT$$interrupt_handler
    call ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_HANDLER
    cmp $0x0, EG(exception)
    jnz JIT$$exception_handler
    cmp $0x452a0858, %r15d
    jnz .L1
    add $0x10, %rsp
    jmp ZEND_RETURN_SPEC_CONST_LABEL

你也可以尝试各种debug的配置,比如opcache.jit_debug=0xff,将会有更多的信息输出。

好了,JIT的使用就简单介绍到这里,关于JIT本身的实现等细节,以后有时间,我再来写吧。

大家现在就可以去php.net下载PHP8来测试了 :)

thanks

点赞
收藏
评论区
推荐文章
技术小男生 技术小男生
6个月前
linux环境jdk环境变量配置
1:编辑系统配置文件vi/etc/profile2:按字母键i进入编辑模式,在最底部添加内容:JAVAHOME/opt/jdk1.8.0152CLASSPATH.:$JAVAHOME/lib/dt.jar:$JAVAHOME/lib/tools.jarPATH$JAVAHOME/bin:$PATH3:生效配置
光头强的博客 光头强的博客
6个月前
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
Stella981 Stella981
1年前
Gif开发笔记(一):gif介绍、编译和工程模板
若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/110530966(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fblog.csdn.net%2Fqq21497936%2Fartic
Stella981 Stella981
1年前
Chrome开发者工具使用指南
好强好强转载自:https://www.cnblogs.com/vvjiang/archive/2020/02/27/12370112.html(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fvvjiang%2Farchive%2F2020%2F
Stella981 Stella981
1年前
Kafka 设计与原理详解 
Kafka设计与原理详解 一、Kafka简介本文综合了我之前写的kafka相关文章,可作为一个全面了解学习kafka的培训学习资料。1转载请注明出处: 本文链接(https://www.oschina.net/action/GoToLink?urlhttp%
Wesley13 Wesley13
1年前
CSS变量(自定义属性)实践指南
本文翻译自:https://www.sitepoint.com/practicalguidecssvariablescustomproperties/转载请注明出处:葡萄城官网(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.grapecity.com.
Wesley13 Wesley13
1年前
Java NIO系列教程(一) Java NIO 概述
详见:http://ifeve.com/overview/原创文章,转载请注明: 转载自并发编程网–ifeve.com(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fifeve.com%2F)本文链接地址: JavaNIO系列教程(一)JavaNIO概述
Stella981 Stella981
1年前
ReactNative For Android 框架启动核心路径剖析
版权声明:本文由王少鸣原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/144(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.qcloud.com%2Fcommunity%2Farticle%2F1
Stella981 Stella981
1年前
Linux下安装rabbitmq
原文地址,转载请注明出处: http://blog.csdn.net/qq\_34021712/article/details/72567786(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fblog.csdn.net%2Fqq_34021712%2Farticle%2Fdetails%
Stella981 Stella981
1年前
PyCharm2020激活破解教程
本文内容皆为作者原创,如需转载,请注明出处:https://www.cnblogs.com/xuexianqi/p/12767075.html(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxuexianqi%2Fp%2F12767075.
Wesley13 Wesley13
1年前
C#开发笔记之15
本文由 比特飞(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.byteflying.com%2F) 原创发布,欢迎大家踊跃转载。转载请注明本文地址:https://www.byteflying.com/archives/3412(https://www.os