真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PHP8中的JIT是什么

PHP8中的JIT是什么?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比浙江網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式浙江網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋浙江地區(qū)。費(fèi)用合理售后完善,十多年實(shí)體公司更值得信賴。

JIT 是一種編譯器策略,它將代碼表述為一種中間狀態(tài),在運(yùn)行時(shí)將其轉(zhuǎn)換為依賴于體系結(jié)構(gòu)的機(jī)器碼,并即時(shí)執(zhí)行。在 PHP 中,這意味著 JIT 將為 Zend VM 生成的指令視為中間表述,并以依賴于體系結(jié)構(gòu)的機(jī)器碼執(zhí)行,也就是說(shuō)托管代碼的不再是 Zend VM,而是更為底層的 CPU。

首先,我們來(lái)看一張圖:

PHP8中的JIT是什么

右圖有點(diǎn)錯(cuò)誤就是,當(dāng)JIT以后,下次請(qǐng)求的時(shí)候,會(huì)直接從JIT Buffer中讀取執(zhí)行,后續(xù)我把圖改一下

左圖是PHP8之前的Opcache流程示意圖, 右圖是PHP8中的Opcache示意圖, 可以看出幾個(gè)關(guān)鍵點(diǎn):

  • Opcache會(huì)做opcode層面的優(yōu)化,比如圖中的倆條opcode合并為一條

  • JIT在Opcache優(yōu)化之后的基礎(chǔ)上,再次優(yōu)化,直接生成機(jī)器碼

  • PHP8的JIT是在Opcache之中提供的

  • 目前PHP8只支持x86架構(gòu)的CPU

  • JIT是在原來(lái)Opcache優(yōu)化的優(yōu)化基礎(chǔ)之上進(jìn)行優(yōu)化的,不是替代

事實(shí)上JIT共用了很多原來(lái)Opcache做優(yōu)化的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),比如data flow graph, call graph, SSA等,關(guān)于這部分,后續(xù)如果有時(shí)間,可以單獨(dú)在寫一個(gè)文章來(lái)介紹,今天就只是著重在使用層面。

下載安裝好以后,除掉原有的opcache配置以外,對(duì)于JIT我們需要添加如下配置到php.ini:

opcache.jit=1205
opcache.jit_buffer_size=64M

opcache.jit這個(gè)配置看起來(lái)稍微有點(diǎn)復(fù)雜,我來(lái)解釋下, 這個(gè)配置由4個(gè)獨(dú)立的數(shù)字組成,從左到右分別是(請(qǐng)注意,這個(gè)是基于目前alpha1的版本設(shè)置,一些配置可能會(huì)隨著后續(xù)版本做微調(diào)):

  • 是否在生成機(jī)器碼點(diǎn)時(shí)候使用AVX指令, 需要CPU支持:
    0: 不使用
    1: 使用
  • 寄存器分配策略:
    0: 不使用寄存器分配
    1: 局部(block)域分配
    2: 全局(function)域分配
  • JIT觸發(fā)策略:
    0: PHP腳本載入的時(shí)候就JIT
    1: 當(dāng)函數(shù)第一次被執(zhí)行時(shí)JIT
    2: 在一次運(yùn)行后,JIT調(diào)用次數(shù)最多的百分之(opcache.prof_threshold * 100)的函數(shù)
    3: 當(dāng)函數(shù)/方法執(zhí)行超過(guò)N(N和opcache.jit_hot_func相關(guān))次以后JIT
    4: 當(dāng)函數(shù)方法的注釋中含有@jit的時(shí)候?qū)λM(jìn)行JIT
    5: 當(dāng)一個(gè)Trace執(zhí)行超過(guò)N次(和opcache.jit_hot_loop, jit_hot_return等有關(guān))以后JIT
  • JIT優(yōu)化策略,數(shù)值越大優(yōu)化力度越大:
    0: 不JIT
    1: 做opline之間的跳轉(zhuǎn)部分的JIT
    2: 內(nèi)斂opcode handler調(diào)用
    3: 基于類型推斷做函數(shù)級(jí)別的JIT
    4: 基于類型推斷,過(guò)程調(diào)用圖做函數(shù)級(jí)別JIT
    5: 基于類型推斷,過(guò)程調(diào)用圖做腳本級(jí)別的JIT

基于此,我們可以大概得到如下幾個(gè)結(jié)論:

  • 盡量使用12x5型的配置,此時(shí)應(yīng)該是效果最優(yōu)的

  • 對(duì)于x, 如果是腳本級(jí)別的,推薦使用0, 如果是Web服務(wù)型的,可以根據(jù)測(cè)試結(jié)果選擇3或5

  • @jit的形式,在有了attributes以后,可能變?yōu)?>

現(xiàn)在,我們來(lái)測(cè)試下啟用和不啟用JIT的時(shí)候,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
hash2(50000)       0.013
hash3(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

根據(jù)上面的介紹,我們選擇opcache.jit=1205, 因?yàn)閎ench.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
hash2(50000)       0.011
hash3(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

可見,對(duì)于Zend/bench.php, 相比不開啟JIT,開啟了以后,耗時(shí)降低將近60%,性能提升將近2倍。

對(duì)于大家研究學(xué)習(xí)來(lái)說(shuō),可以通過(guò)opcache.jit_debug來(lái)觀測(cè)JIT后生成的匯編結(jié)果,比如對(duì)于:

function simple() {
  $a = 0;
  for ($i = 0; $i < 1000000; $i++)
    $a++;
}

我們通過(guò)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

大家可以嘗試閱讀這段匯編,比如其中針對(duì)i的遞增,可以看到優(yōu)化力度很大,比如因?yàn)閕是局部變量直接分配在寄存器中,i的范圍推斷不會(huì)大于10000,所以不需要判斷是否整數(shù)溢出等等。

而如果我們采用opcache.jit=1201, 我們可以得到如下結(jié)果:

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

這就只是簡(jiǎn)單的內(nèi)斂部分opcode handler的調(diào)用了。

你也可以嘗試各種opcache.jit的策略結(jié)合debug的配置,來(lái)觀測(cè)結(jié)果的不同,你也可以嘗試各種opcache.jit_debug的配置,比如0xff,將會(huì)有更多的輔助信息輸出。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。


分享題目:PHP8中的JIT是什么
當(dāng)前路徑:http://weahome.cn/article/iicogd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部