1 / 17
文档名称:

深入理解 PHP opcode 优化 – 码农网.doc

格式:doc   大小:20KB   页数:17页
下载后只包含 1 个 DOC 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

深入理解 PHP opcode 优化 – 码农网.doc

上传人:巧姐 2022/1/27 文件大小:20 KB

下载得到文件列表

深入理解 PHP opcode 优化 – 码农网.doc

文档介绍

文档介绍:深入理解 PHP opcode 优化 – 码农网

PHP()作为一门动态脚本语言,其在zend虚拟机执行过程为:读入脚本程序字符串,经由词法分析器将其转换为单词符号,接着语法分析ONST),只读常量,值不可被更改。
无用变量(UNUSED)。由于opcode采用三地址码,不是每一个opcode均有操作数字段,缺省时用该变量补齐字段。
类型信息与操作符一起,供执行器匹配选择特定已编译好的C函数库模板,模拟生成机器指令来执行。
opcode在ZendVM中以zend_op结构体来表征,其主体结构如下:
optimizer优化器
PHP脚本经过词法分析、语法分析生成抽象语法树结构后,再经静态编译生成opcode。它作为向不同的虚拟机执行指令的公共平台,依赖不同的虚拟机具体实现(然对于PHP来说,大部分是指ZendVM)。
在虚拟机执行opcode之前,如果对opcode进行优化可得到执行效率更高的代码,pass的作用就是优化opcode,它作用于opcde、处理opcode、分析opcode、寻找优化的机会并修改opcode产生更高执行效率的代码。
1)ZendVM优化器简介
在Zend虚拟机(ZendVM)中,opcache的静态代码优化器即为zend opcode optimization。
为观察优化效果及便于调试,它也提供了优化与调试选项:
optimizationlevel (=0xFFFFFFFF) 优化级别,缺省打开大部分优化遍,用户亦通过传入命令行参数控制关闭
optdebuglevel (=-1) 调试级别,缺省不打开,但提供了各优化前后opcode的变换过程
执行静态优化所需的脚本上下文信息则封装在结构zend_script中,如下:
typedef struct _zend_script {
zend_string *filename; //文件名
zend_op_array main_op_array; //栈帧
HashTable function_table; //函数单位符号表信息
HashTable class_table; //类单位符号表信息
} zend_script;
上述三个内容信息即作为输入参数传递给优化器供其分析优化。当然与通常的PHP扩展类似,它与opcode缓存模块一起(zend_accel)构成了opcache扩展。其在缓存加速器内嵌入了三个内部API:
zendoptimizerstartup 启动优化器
zendoptimizescript 优化器实现优化的主逻辑
zendoptimizershutdown 优化器产生的资源清理
关于opcode缓存,也是opcode非常重要的优化。其基本应用原理是大体如下:
虽然PHP作为动态脚本语言,它并不会直接调用GCC/LLVM这样的整套编译器工具链,也不会调用Javac这样的纯前端编译器。但每次请求执行PHP脚本时,都经历过词法、语法、编译为opcode、VM执行的完整生命周期。
除去执行外的前三个步骤基本就是一个前端编译器的完整过程,然而这个编译过程并不会快。假如反复执行相同的脚本,前三个步骤编译耗时将严重制约运行效率,而每次编译生成的opcode则没有变化。因此可在第一次编译时把opcode缓存到某一个地方,opcache扩展即是将其缓存到共享内存(Java则是保存到文件中),下次执行相同脚本时直接从共享内存中获取opcode,从而省去编译时间。
opcache扩展的opcode 缓存流程大致如下:
由于本文主要集中讨论静态优化遍,关于缓存优化的具体实现此处不展开。
2)ZendVM优化器原理
依“鲸书”(《高级编译器设计与实现》)所述,一个优化编译器较为合理的优化遍顺序如下:
上图中涉及的优化从简单的常量、死代码到循环、分支跳转,从函数调用到过程间优化,从预取、缓存到软流水、寄存器分配,当然也包含数据流、控制流分析。
当然,当前opcode优化器并没有实现上述所有优化遍,而且也没有必要实现机器相关的低层中间表示优化如寄存器分配。
opcache优化器接收到上述脚本参数信息后,找到最小编译单位。以此为基础,根据优化pass宏及其对应的优化级别宏,即可实现对某一个pass的注册控制。
注册的优化中,按一定顺序组织串联各优化,包含常量优化、冗余nop删除、函数调用优化的转换pas