2021-05-12 14:32:11
PHP8.0新特性:JIT即時編譯
JIT編譯原理
一.檢視JIT編譯原理圖
二.Zend Opcache作用1.檢查opcodes是否快取2.zend compiler編譯器進行編譯生成opcodes3.optimizer優化器生成優化後的opcodes4.把優化後的opcodes放入opcodes cache快取5.經過zend vm虛擬機器生成opcodes handlers處理程式6.送入x86 cpu架構進行執行三.JIT編譯原理1.檢查opcodes是否快取2.zend compiler編譯器進行編譯生成opcodes3.optimizer優化器生成優化後的opcodes4.把優化後的opcodes放入opcodes cache快取5.jit編譯器把optimized opcodes再次編譯成彙編機器碼machine codes6.進入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指令碼載入的時候就JIT1: 當函數第一次被執行時JIT2: 在一次運行後,JIT呼叫次數最多的百分之(opcache.prof_threshold * 100)的函數3: 當函數/方法執行超過N(N和opcache.jit_hot_func相關)次以後JIT4: 當函數方法的註釋中含有@jit的時候對它進行JIT5: 當一個Trace執行超過N次(和opcache.jit_hot_loop, jit_hot_return等有關)以後JIT4.JIT優化策略,數值越大優化力度越大0: 不JIT1: 做opline之間的跳轉部分的JIT2: 內斂opcode handler呼叫3: 基於類型推斷做函數級別的JIT4: 基於類型推斷,過程呼叫圖做函數級別JIT5: 基於類型推斷,過程呼叫圖做指令碼級別的JIT三.JIT配置1.disable在啟動時完全禁用JIT功能,並且在運行時無法啟用2.off禁用,但是可以在運行時啟用JIT3.on啟用tracing模式4.tracing數值配置的別名12545.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的語言引擎Zend1.Scanning(Lexing) ,將PHP程式碼轉換為語言片段(Tokens)2.Parsing, 將Tokens轉換成簡單而有意義的表示式3.Compilation, 將表示式編譯成Opocdes4.Execution, 順次執行Opcodes,每次一條,從而實現PHP指令碼的功能
四.Scanning
#用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 string2.add two numbers together3.store the result of the prior expression to a variable4.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.ini1.使用數值opcache.jit=1235opcache.jit_buffer_size=64M2.使用簡單標記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
相關文章