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.交流群: 2702237 13835667

相關課文
  • mac開發接入微信公衆號接口返回報錯 cURL error 56: SSLRead() return error -9806

  • PHP的換行符是什麽

  • pecl安裝程序時報錯Array and string offset access syntax with curly braces is no longer supported

  • 由於商家傳入的H5交易參數有誤,該筆交易暫時無法完成,請聯繫商家解決

我要說說
網上賓友點評