opcache和jit

533 阅读2分钟

PHP执行代码过程

php每次请求都会经历以下步骤

  1. 启动Zend引擎,加载配置,加载模块
  2. Scaning:扫描 ,也叫Lexing,把人类写的代码转换成语言片段(Tokens)
  3. Parsing:解析,将语言片段转换成简单表达式
  4. Compilation: 编译, 将表达式编译成opcode(字节码)
  5. Execution: 执行,zend vm顺序执行opcode

cli/cgi 模式每次都要执行全部步骤,php-fpm可以省略第一步,启用opcache时,可以省略2,3,4步

opcache

开启opcache,将opcode缓存起来(内存中),可以省略PHP执行的1,2步骤,直接执行opcache中的opcache。

可以极大减少CPU和内存开销,但对I/O密集的提升不是很大

如图:开启opcache会增加执行步骤

  1. 执行前判断是否存在opcache
  2. 首次执行会将opcode缓存起来
//opcache扩展位置
zend_extension=opcache.so

//启用opcache
opcache.enable=1

使用共享内存大小
opcache.memory_consumption=200

文件检测周期,以下2个配置代表3600秒更新1次缓存
revalidate_freq=3600  //3600秒更新1次缓存
opcache.validate_timestamps=1;//为0时revalidate_freq被忽略



opcache缺点

  1. 额外占用内存用来存储opcache
  2. 代码不能马上生效,要等缓存更新了才能生效 (revalidate_freq)

开头使用opcache_reset()函数,或者重启服务器来清空缓存

jit

PHP新加入,适合cpu密集型性能提升,JIT不是原来Opcache优化的替代,是增强

JIT在Opcache优化之后的基础上,再次优化,直接生成机器码,直接由CPU执行(不在需要ZEND VM虚拟机执行),目前PHP8只支持x86架构的CPU

PHP8的JIT是在Opcache之中提供的,集成在Opcache中

过程:

再生成opcode后,zend VM判断是否开启jit,未开启则zend VM接管,若开启了jit, 如果开启,则读取机器码中的jit buffer代码片段(以前缓存好的),直接让CPU托管执行。

PHP7常用新特性

  1. ?? 运算符
  2. 函数返回值类型声明,declare(strict_types=1) 声明强制模式
  3. 函数参数类型声明
  4. use批量声明
use some/namespace/{ClassA, ClassB, ClassC as C}; 
  1. <=> 太空船运算符
$a = 1;
$b = 2;
$c = $a<=>$b;
echo $c; //a:b 小中大分别返回 -1,0,1

PHP8常用新特性