PHP8新特性之JIT案例的示例分析

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

首先,我们来看一张图:

PHP8新特性之JIT案例的示例分析

左图是 PHP 8之前的Opcache流程示意图, 右图是 PHP 8中的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

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

尽量使用12×5型的配置,此时应该是效果最优的

对于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

hash2(50000) 0.013

hash3(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

hash2(50000) 0.011

hash3(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,将会有更多的信息输出。

原创文章,作者:DOHDL,如若转载,请注明出处:http://www.wangzhanshi.com/n/15282.html

(0)
DOHDL的头像DOHDL
上一篇 2025年1月2日 12:17:55
下一篇 2025年1月2日 12:17:59

相关推荐

  • 关于php7.0下Sqli-labs搭建的小问题

    由于前文中kali版本较新,默认安装的是php7.0(this is the problem)PHP 5 的使用者可以使用 mysql extension,mysqli 和 PDO…

    php 2025年1月1日
  • Deep Module深模块之软件设计实例分析

    1,模块化设计 在模块设计中,软件系统被分解为相对独立的模块集合。模块的形式多种多样,可以是类、子系统、或服务等。在理想的世界中,每个模块都完全独立于其它模块:开发者在任何模块中工…

    2025年1月2日
  • 如何在Linux中安装卸载php7

    Linux简介 Linux,全称GNU/Linux,是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。伴…

    2025年1月1日
  • mac如何编译安装 php7

    mac编译安装php7的方法:1、通过“wget -c http://mirrors.sohu.com/php/php-7.1.8.tar.gz”下载PHP;2、通过“tar -z…

    php 2025年1月1日
  • 如何在CentOS中安装PHP7

    CentOS上的PHP版本都十分古老,满足不了一些框架对PHP版本的要求。于是,出现了许多第三方软件库,如EPEL、RPM Fusion、Remi等,这些库提供了新版的PHP。让我…

    php 2025年1月1日
  • PHP5接口和抽象类的语法介绍

    大家对PHP5接口和PHP5抽象类的语法了解有多少呢?下面我们就为那些刚刚接触PHP语言的同仁们介绍一下PHP5接口和PHP5抽象类的具体语法,希望对又需要的朋友有所帮助。 具体P…

    php 2025年1月2日
  • php7的特性有哪些

    新特性预览 ZEND引擎升级到Zend Engine 3,也就是所谓的PHP NG 增加抽象语法树,使编译更加科学 64位的INT支持 统一的变量语法…

    2025年1月1日
  • PHP7中使用“DES-EDE-CBC”加解密的方法

    1. 条件约束 之前PHP5上常使用的mcrypt库在PHP7.1+上已经被移除,故我们采用openssl对数据进行加解密。 加密方式采用DES-EDE-CBC方式。 密钥填充方式…

    php 2025年1月1日
  • php基础教程

    php简介 当前网络技术发展日新月异,各种基于服务端创建动态网站的脚本语言更是层出不穷。其中PHP以其简单、易用、可移植性强等特点,在众多的动态网站语言技术中独树一帜。那么到底什么…

    php 2024年12月17日
  • apache中不解析php7如何解决

    解决Apache无法解析PHP问题 编辑httpd.conf文件 添加如下代码 LoadModule php7_module modules/libphp7.s…

    php 2025年1月1日

发表回复

登录后才能评论