- 本文地址: https://www.laruence.com/2020/06/27/5963.html
- 转载请注明出处
PHP8 alpha1已经在昨天发布,相信关于JIT是大家最关心的,它到底怎么用,有什么要注意的,以及性能提升到底咋样?
左图是PHP8之前的Opcache流程示意图, 右图是PHP8中的Opcache示意图, 可以看出几个关键点:
- Opcache会做opcode层面的优化,比如图中的俩条opcode合并为一条
- PHP8的JIT目前是在Opcache之中提供的
- JIT在Opcache优化之后的基础上,结合Runtime的信息再次优化,直接生成机器码
- JIT不是原来Opcache优化的替代,是增强
- 目前PHP8只支持x86架构的CPU
事实上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>>
现在,我们来测试下启用和不启用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
大家可以尝试阅读这段汇编,比如其中针对i的递增,可以看到优化力度很大,比如因为i是局部变量直接分配在寄存器中,i的范围推断不会大于1000000,所以不需要判断是否整数溢出等等。
而如果我们采用opcache.jit=1005, 如前面的介绍,也就是不使用寄存器分配,可以得到如下结果:
JIT$simple: ; (/tmp/1.php) sub $0x10, %rsp mov $0x0, 0x50(%r14) mov $0x4, 0x58(%r14) jmp .L2 .L1: add $0x1, 0x50(%r14) .L2: cmp $0x0, EG(vm_interrupt) jnz .L4 cmp $0xf4240, 0x50(%r14) 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 $0x44cdb818, %r15 jmp JIT$$interrupt_handler
可以看到针对i的部分,现在是在内存操作,并没有使用寄存器。
再如果我们采用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
这就只是简单的内敛部分opcode handler的调用了。
你也可以尝试各种opcache.jit的策略结合debug的配置,来观测结果的不同,也可以尝试各种opcache.jit_debug的配置,比如0xff,将会有更多的辅助信息输出。
好了,JIT的使用就简单介绍到这里,关于JIT本身的实现等细节,以后有时间,我再来写吧。
大家现在就可以去php.net下载PHP8来测试了 :)
thanks
Birla Trimaya offers a diverse range of residential options, catering to the varying needs and preferences of homebuyers.
perfect thanks for all your help and advice on how to the information
i like PHP
Thanks
perfect thanks so grateful for your help and support
very much happy for the information contained in this
Godrej Ananda Residence is a masterpiece development by Godrej Properties, a renowned name in the real estate industry. Located in the heart of Bangalore, this project offers a perfect blend of contemporary design, world-class amenities
Sobha Neopolis is a prestigious residential project located in Bangalore, specifically in Panathur Road. Developed by Sobha Limited.
please let me know if you have any questions
Nice Blog… Keep Posting
Welcome to Gudlu Resort, a hidden gem nestled amidst the picturesque hills of Mudigere in Chikmagalur. If you are looking for a resorts in Mudigere , Gudlu Resort is the place to be. Surrounded by acres of lush greenery, Gudlu Resort offers a range of luxurious accommodations that are perfect for couples, families, and groups. Each room is well-appointed with modern amenities and offers breathtaking views of the surrounding hills and valleys.
Welcome to Tattvamretreat Resort, Bangalore – a serene and tranquil Retreat near Bangalore that offers a holistic approach to wellness through Ayurveda and Yoga. Tucked away amidst lush greenery and rolling hills, Tattvamretreat Resort is a perfect getaway for those seeking a peaceful and rejuvenating experience.
Welcome to Gari Resort, Bangalore – one of the best resorts for stay in Bangalore that offers a unique blend of luxury, comfort, and relaxation. If you are looking for the perfect escape from the hustle and bustle of city life, Gari Resort is the place for you.
Thanks for sharing .. looking forward for it.
Bigo88 merupakan situs terpercaya yang ada di indonesia dan telah dipercaya oleh ratusan bahkan ribuan pemain yang memainkan permainan slot maupun judi online di indonesia..
Bigo88 merupakan situs terpercaya yang ada di indonesia dan telah dipercaya oleh ratusan bahkan ribuan pemain yang memainkan permainan slot maupun judi online di indonesia.
Stay warm and stylish with the kevin costner yellowstone jacket. Shop now and get ready for the cold weather in style. Buy Today!
very good
Provident Ecopoliten is an upcoming residential project in Bangalore that offers luxurious living spaces and contemporary amenities
Thanks for sharing this valuable information! Your insights on this topic were really helpful and I appreciate the time and effort you put into creating this post. Looking forward to reading more from you in the future!
good
Nice post
check out new tamil love quotes தமிழ் காதல் கவிதைகள்
Thanks for sharing this article. I am glad to see this amazing post.
Your post makes sense, and it piqued my interest. It provides me with a wealth of critical information, for which I am grateful.
Ahh that is great thank you ! Good for special needs too !
[…] CPU.其较之前的流程改动和重点如下(来源于PHP8 JIT的主要参与者鸟哥@风雪之隅)左图是PHP8之前的Opcache流程示意图, 右图是PHP8中的Opcache示意图, […]
[…] 左边是 PHP 采用 Opcache 的 执行流程,右边是加入了 JIT 的执行流程。一方面,JIT 是对 Opcache 的增强;另一方面 JIT 可以将优化后的 opcodes 直接编译成机器码,对于已经编译成机器码的,就跳过了 Zend 虚拟机交由 CPU 执行了。更多的细节,可以参考鸟哥的《PHP 8新特性之JIT简介》。 […]
鸟哥看这里,
你现在是弄链家VR了不弄PHP了吗?
之前看你的文章,觉得你好像和php官方那边弄得不愉快…
jit之后你还会参与PHP的开发吗?
啥时候给FreeBSD加上? 测试了Win下都有, FreeBSD竟然没有jit…
今天刚刚给 FreeBSD12.1 下 PHP 升级到 PHP8.0.1 了, 已经修复了此 Jit 问题…
jit并不能大面积提升PHP在web领域的性能,但可以进军后台运算领域,但是话又说回来像python这么慢的语言已经火的发紫了,我觉得开拓PHP的使用领域大家应该重视起来,而且PHP对操作系统底层的封装还不够完善导致很多功能使用PHP无法实现。
~~期待!
Event 挺好使的, 但是不能代替进程线程
Merk kaca film gedung hemat kekuatan dan fungsinya. Kaca film gedung terdiri dari banyak merk,type dan tipe,dari mulai kelas standard sampai kelas bonafit. klik https://kacafilm-vkool.netlify.app/sticker-kaca-film-v-kool-40-bmw-520i.html jika Anda tertarik
PHP 这种解释性语言,不加快异步IO支持,淘汰速度将大大加快,10年左右PHP的使用人数和现在天壤之别,开发快的特点也要快被前端组件化的开发趋势取代
are you sure?yield can do async,php rely in nginx + fscgi too much not like other js,go,java ettc that can do self web containers more efficent.So support from nginx plus fscgi(may be refactor again) is more important then php it self.
开启失败……
opcache.enable=on
opcache.jit=1205
opcache.jit_buffer_size=128M
phpinfo看的还是 JIT : Not Available
建议您检查一下php.ini内有没有加上下面这个语句,不然确实是不可用的。
zend_extension=opcache.so
test
up
没有携程或者线程php必将淘汰
已经在淘汰的边缘
php支持线程,安装个插件就行了,只是fastcgi不是线程,另外同样的cpu下,进程与线程性能相差不大,不信自己用swoole与workman(进程)测试对比一下,就好比排对多却很慢与排队少但很快一样的道理,而且进程比线程更好控制
Event 不好吗? workman 不好吗? 都十几年前的东西了
最近做了非x86的php7项目迁移,jit在php8编译时能完整隔离开,
其实php都是做网站比较多,网站最重要的是io的速速,而不是计算能力,希望php能加入异步的io和多线程或者协程,这样才是现在php最重要的,个人见解不喜勿喷!
以目前PHP情况 加入多线程绝壁是灾难的开始.
我也觉得是,加入异步io和多线程或者协程,这才是最重要的,而不是计算能力。
php支持线程,安装个插件就行了,只是fastcgi不是线程,另外同样的cpu下,进程与线程性能相差不大,不信自己用swoole与workman(进程)测试对比一下,就好比排对多却很慢与排队少但很快一样的道理,而且进程比线程更好控制
想异步,一个ajax就解决了,想多线程,装个插件就解决了
。。。
hhhhhhhhhha
把我看笑了
难怪phper会被人鄙视😒 就是你这样的人弄的
你倒不如直接说语言级别,async await 异步实现呢,现在Python3.4都支持了,C#很早就有了。
[…] PHP 8新特性之JIT简介 […]
不好意思上面那条评论中,我没有开启opache,开启之后,确实快了很多!
php.ini
zend_extension=opcache
[opcache]
opcache.jit=1205
opcache.jit_buffer_size=64M
; Determines if Zend OPCache is enabled
opcache.enable=1
; Determines if Zend OPCache is enabled for the CLI version of PHP
opcache.enable_cli=1
再次运行结果
不带JIT
➔ /usr/local/opt/php@8.0-alpha/bin/php -d opcache.jit_buffer_size=0 Zend/bench.php
…
————————
Total 0.487
带JIT:
➔ /usr/local/opt/php@8.0-alpha/bin/php -d opcache.jit_buffer_size=64M -d opcache.jit=1205 Zend/bench.php
…
————————
Total 0.135
niceeeee!
我在MacbookPro上通过源码编译安装好了PHP8.0 alpha3,但是我试了一下带不带JIT好像差别不大(甚至效果更差),很多次基本上都是这样的,请问哪里出问题了,CPU型号:2.7 GHz 双核Intel Core i5
不带JIT:
“`
➔ /usr/local/opt/php@8.0-alpha/bin/php -d opcache.jit_buffer_size=0 Zend/bench.php
simple 0.025
simplecall 0.008
<?php
simpleucall 0.030
simpleudcall 0.037
mandel 0.127
mandel2 0.123
ackermann(7) 0.034
ary(50000) 0.011
ary2(50000) 0.005
ary3(2000) 0.056
fibo(30) 0.121
hash1(50000) 0.015
hash2(500) 0.011
heapsort(20000) 0.037
matrix(20) 0.031
nestedloop(12) 0.041
sieve(30) 0.019
strcat(200000) 0.008
————————
Total 0.739
“`
带JIT:
➔ /usr/local/opt/php@8.0-alpha/bin/php -d opcache.jit_buffer_size=64M -d opcache.jit=1205 Zend/bench.php
simple 0.025
simplecall 0.009
simpleucall 0.029
simpleudcall 0.034
mandel 0.115
mandel2 0.135
ackermann(7) 0.039
ary(50000) 0.008
ary2(50000) 0.006
ary3(2000) 0.061
fibo(30) 0.132
hash1(50000) 0.013
hash2(500) 0.013
heapsort(20000) 0.042
matrix(20) 0.041
nestedloop(12) 0.048
sieve(30) 0.020
strcat(200000) 0.010
————————
Total 0.778
x 是变量。。。哈哈哈哈哈 1205 1215 1225 等等 x是触发策略
其实我看不懂 “12×5型的配置” 的意思
是否可以给个设置的范例?
谢谢
12×5就是第一个 ,第二个 第四个分别选择 1,2,5 第三个根据情况来定
国人的骄傲
你骄傲啥啊!!!!!!!
up
关注新变化
更希望官方实现协程,异步IO,而不是使用swoole
是啊,目前更期待的是这些,而不是JIT
如果能将Swoole纳入官方维护的话,还是考虑用Swoole的,现在Swoole在中小型企业不被认可,大部分Swoole能做的事情都让Go或者Java处理了,Swoole现在给我的感觉就是商业化严重,中小型企业不愿意试错,但是不得不说Swoole确实重新定义了PHP。
“大部分Swoole能做的事情都让Go或者Java处理了”, 这句话深有感触啊!
//yield 就是协程的一种 但个人真的不好用,还有底层阻塞的问题等 异步编程参照JS的进化 callback->yield->await+async RUST直接采用最后await+async+future
//swoole的封装个人感觉有些粗暴,代码质量 额,跟PHP官方代码确实有些差距,php C层面如果可以把异步操作弄个统一的收归,官方可以弄个牛逼点yield的调度器,顺带加个channel 觉得就没使用swoole的必要了
//要快速开发的,我还是用PHP,对于极端的接口 我用 actix-web 我知道很多PHP转GO的.萝卜白菜各有所爱. 作为PHP转RUST的表示用GO还是算了吧,没感觉有什么大优势
我更希望 PHP 能支持多线程+协程,类似 go 的模型。swoole 也只是单线程+协程,为了利用多核就只能多进程,这样除了协程间的 channel 通信,还需要进程间通信。本来用PHP就是为了写起来快,简单,通信这里却更复杂了。
go出现的时候CPU已经是多核了,在多核时代go在设计的时候就考虑到了,所以golang语言实现的应用能跑满所有的核。
但是PHP被设计的时候,PHP只有单核的,就像2维生物无法想象3维空间,在设计时PHP就是照着单核设计的,所以要求PHP来实现类似golang的特性有点难为人了。
你说到了广大PHPer目前面临的窘境和痛点
up
jit 特性,可不可以使用php写extension?是真的吗?
-dopcache.jit=0xxx 会报 warning:Invalid “opcache.jit” setting. Should be “disable”, “on”, “off” or 4-digit number in Unknown on line 0
厉害!!~~期待!
JIT终于来了,期待一下
PHP很优秀哦
up2
up