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交易參數有誤,該筆交易暫時無法完成,請聯系商家解決

我要說說
網上賓友點評