PHP

PHP8.0新特性:JIT即时编译

字号+ 编辑: Snake 修订: 种花家 来源: PHP自学中心 2023-09-11 我要说两句(0)

JIT是“Just In Time”的首字母缩写。每当一个程序在运行时创建并运行一些新的可执行代码,而这些代码在存储于磁盘上时不属于该程序的一部分,它就是一个JIT。

JIT编译原理

一、查看JIT编译原理图

1111.jpg

二、Zend Opcache作用

1、检查opcodes是否缓存

2、zend compiler编译器进行编译生成opcodes

3、optimizer优化器生成优化后的opcodes

4、把优化后的opcodes放入opcodes cache缓存

5、经过zend vm虚拟机生成opcodes handlers处理程序

6、送入x86 cpu架构进行执行

三、JIT编译原理

1、检查opcodes是否缓存

2、zend compiler编译器进行编译生成opcodes

3、optimizer优化器生成优化后的opcodes

4、把优化后的opcodes放入opcodes cache缓存

5、jit编译器把optimized opcodes再次编译成汇编机器码machine codes

6、进入zend vm虚拟前先检查是否开启jit引擎

7、如果已经开启了jit引擎则直接读取机器码中的jit buffer代码片段

8、送入x86 cpu架构进行执行

四、Opcache示意图的关键点

1、Opcache会做opcode层面的优化,比如图中的两条opcode合并为一条

2、PHP8的JIT目前是在Opcache之中提供的

3、JIT在Opcache优化之后的基础上,结合Runtime的信息再次优化,直接生成机器码

4、JIT不是原来Opcache优化的替代,是增强

5、目前PHP8只支持x86架构的CPU

Tracing JIT和Function JIT编译引擎

一、JIT功能开启

#php.iniopcache.jit=1205opcache.jit_buffer_size=64M

二、opcache.jit说明

1、是否在生成机器码的时候使用AVX指令, 需要CPU支持

    0: 不使用

    1: 使用

2、寄存器分配策略

    0: 不使用寄存器分配

    1: 局部(block)域分配

    2: 全局(function)域分配

3、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

4、JIT优化策略,数值越大优化力度越大

    0: 不JIT

    1: 做opline之间的跳转部分的JIT

    2: 内敛opcode handler调用

    3: 基于类型推断做函数级别的JIT

    4: 基于类型推断,过程调用图做函数级别JIT

    5: 基于类型推断,过程调用图做脚本级别的JIT

三、JIT配置

1、disable在启动时完全禁用JIT功能,并且在运行时无法启用

2、off禁用,但是可以在运行时启用JIT

3、on启用tracing模式

4、tracing数值配置的别名1254

5.function数值配置的别名1205

四、JIT实用配置

opcache.jit=tracingopcache.jit_buffer_size=64M

Opcodes编译原理

一、opcodes作用opcodes是一种php脚本编译后的中间语言,就像java的bytecode,或者.net的msl

二、原生php代码

<?php 
    echo "Hello World"; 
    $a = 1 + 1; 
    echo $a;
?>

三、PHP执行这段代码会经过如下4个步骤

#PHP的语言引擎Zend

1、Scanning(Lexing) ,将PHP代码转换为语言片段(Tokens)

2、Parsing, 将Tokens转换成简单而有意义的表达式

3、Compilation, 将表达式编译成Opocdes

4、Execution, 顺次执行Opcodes,每次一条,从而实现PHP脚本的功能

四、Scanning

1、#用token_get_all处理以上PHP原生代码#

index.php

<?php
    $str='<?php echo "Hello World"; $a = 1 + 1; echo $a;?>';
    $arr=$tokens=token_get_all($str);
    echo "<pre>";
    print_r($arr);
    echo "</pre>";

Array( [0] => Array ( [0] => 367 [1] => Array ( [0] => 316 [1] => echo ) [2] => Array ( [0] => 370 [1] => ) [3] => Array ( [0] => 315 [1] => "Hello World" ) [4] => ; [5] => Array ( [0] => 370 [1] => ) [6] => = [7] => Array ( [0] => 370 [1] => ) [8] => Array ( [0] => 305 [1] => 1 ) [9] => Array ( [0] => 370 [1] => ) [10] => + [11] => Array ( [0] => 370 [1] => ) [12] => Array ( [0] => 305 [1] => 1 ) [13] => ; [14] => Array ( [0] => 370 [1] => ) [15] => Array ( [0] => 316 [1] => echo ) [16] => Array ( [0] => 370 [1] => ) [17] => ;)

2、Parsing

#接下来,就是Parsing阶段了,Parsing首先会丢弃Tokens Array中的多余的空格,将剩下的转成一个一个的简单的表达式

    1.echo a constant string

    2.add two numbers together

    3.store the result of the prior expression to a variable

    4.echo a variable

3、Compilation

#它会把Tokens编译成一个个op_array* ZEND_ECHO 'Hello World'* ZEND_ADD ~0 1 1* ZEND_ASSIGN !0 ~0* ZEND_ECHO !0> ```

4、由Zend引擎一行一行读取并执行.

Opcache和JIT功能开启

一、opcache配置

#php.inizend_extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20200930/opcache.soopcache.enable=1opcache.enable_cli=1

二、jit配置

#php.ini

1、使用数值opcache.jit=1235opcache.jit_buffer_size=64M

2、使用简单标记opcache.jit=tracingopcache.jit_buffer_size=64M

三、检测

#php文件phpinfo();

JIT高性能测试

一、PHP原生代码

#index.php<?php $a=1; $b=2; $c=$a+$b;?>

二、获得JIT汇编后的机器码

#/usr/local/php/bin/php/usr/local/php/bin/php -d opcache.jit=1205 -d opcache.jit_debug=0x01 index.php/usr/local/php/bin/php -d opcache.jit=function -d opcache.jit_debug=0x01 index.phpJIT$simple: ; (/tmp/1.php) sub $0x10, %rsp xor %rdx, %rdx jmp .L2.L1: add $0x1, %rdx

三、JIT基准测试

#Zend/bench.php#cp /mnt/php-8.0.0/Zend/bench.php /usr/local/nginx/html/bbs/

1、jit禁用

/usr/local/php/bin/php -d opcache.jit_buffer_size=0 bench.php/usr/local/php/bin/php -d opcache.jit=disable bench.php

2、jit开启

/usr/local/php/bin/php -d opcache.jit_buffer_size=64M -d opcache.jit=1205 bench.php/usr/local/php/bin/php -d opcache.jit=tracing bench.php

四、JIT计算压力测试

#index.php<?php $a=1; $b=2; $c=$a+$b;?>

#win abab -n10 -c10 http://bbs.linux.com/index.phpab -n1000 -c1000 http://bbs.linux.com/index.phpab -n10000 -c10000 http://bbs.linux.com/index.php

五、JIT WEB压力测试

#index.phpphpinfo();

#win abab -n10 -c10 http://bbs.linux.com/index.phpab -n1000 -c1000 http://bbs.linux.com/index.phpab -n10000 -c10000 http://bbs.linux.com/index.php

阅完此文,您的感想如何?
  • 有用

    16

  • 没用

    3

  • 开心

    1

  • 愤怒

    8

  • 可怜

    0

1.如文章侵犯了您的版权,请发邮件通知本站,该文章将在24小时内删除;
2.本站标注原创的文章,转发时烦请注明来源;
3.交流群: PHP+JS聊天群

相关课文
  • mac开发接入微信公众号接口返回报错 cURL error 56: SSLRead() return error -9806

  • pecl安装程序时报错Array and string offset access syntax with curly braces is no longer supported

  • PHP的换行符是什么

  • 由于商家传入的H5交易参数有误,该笔交易暂时无法完成,请联系商家解决

我要说说
网上宾友点评