文档开发者中心
我的

ARM64使能寄存器变量,PHP Zend引擎提升10%+性能

今年做PHP 在ARM上的性能性能优化,利用GCC全局寄存器特性使提升PHP在aarch64上性能提升10%。

源码修改已经提交到官方社区,随PHP 7.4以上官方版本发布。

发一篇帖子记录一下,对于PHP 7 , 不愿意升级PHP版本的,也可以修改几行代码,重新编译安装即可。

顺便总结了一下,利用GCC全局寄存器性能提升的内部原理和可用的推广点。

此性能优化点在PHP的Zend引擎中,任何使用PHP的场景都适用。

1 源码修改

源码修改涉及的2个文件如表1.所示。

表1. 源码修改涉及文件

修改文件Zend_execute.czend.m4
源文件描述源码宏定义通用宏处理器,configure脚本依赖它

2个文件修改的内容均一致,总计新增3x2=6行代码。

修改后代码和源码对比如图1.所示。


图1. PHP源码修改点

通过编译器的宏进行GCC版本判断和CPU类别判断,选取ARM64后两个通用寄存器x27和x28。寄存器的使用方法如图2.所示。


图2. Zend中寄存器使用

在并发访问worepress首页的场景中,获得了10%以上的性能提升。源码已合入PHP官方社区,将在PHP 7.4及以上版本发布。

2 内部原理

PHP 的Zend引擎在opcode的执行过程中,会频繁的用到execute_data(执行数据)和opline(当前执行的指令)两个变量。优化前的软件流程参考普通处理方式,优化后的软件流程参考全局寄存处理方式。


普通的处理方式


执行每条opcode指令的handler时,会把execute_data地址作为参数传给handler使用,先从当前栈上获取execute_data地址,然后再从堆上获取变量的数据(在缓存命中的情况下,从缓存中获取数据)。


GCC全局寄存器处理方式


使用GCC提供的全局寄存器特性保存execute_data和opline变量的地址在寄存器中,直接从寄存器读取地址。相对普通处理方式,节省了从缓存/内存中读取数据的时间。

3 技术推广

将频繁使用的char、int或指针型变量存储在寄存器中,使用4.8.0以上GCC进行源码编译

4 附录

寄存器变量


寄存器变量存放在CPU的寄存器中,使用时,不需要访问内存直接从寄存器中读写,与存储在内存中的变量相比,寄存器变量具有更快的访问速度。 C语言中使用关键字register来声明变量为寄存器变量。受硬件寄存器长度的限制,寄存器变量只能是char、int或指针型,而不能使其他复杂数据类型。


全局寄存器变量


GCC从4.8.0版本开始支持另外一项特性:全局寄存器变量(Global Register Variables),可以把全局变量定义为寄存器变量,从而可以实现函数间共享数据。可以通过下面的语法告诉编译器使用寄存器来保存数据:


图3 寄存器变量声明语法

全局寄存器变量详细介绍参考链接:



点赞
2
收藏
1
回复
7
分享
举报
浏览1653 发布于2019-11-28 06:14未知归属地
全部评论
最多点赞
最新发布
最早发布
666
8楼回复于2022-12-04 04:47 来自广东

好文章写的真不错、学习收藏了

7楼回复于2021-12-24 13:59 未知归属地
深受大佬文章启发!向大佬好好学习!
5楼回复于2021-12-23 11:43 未知归属地
支持大佬,对我很有收获,期待你更多好的作品
4楼回复于2021-12-16 14:56 未知归属地
好像图片看不到了?
3楼回复于2021-12-06 09:17 未知归属地
讲解的很详细,学到了。
2楼回复于2021-11-17 11:19 未知归属地

干货,顶一顶~~~~~~~~~~~~~~

1楼回复于2019-12-03 06:19 未知归属地
写回答
新增插入模板功能
一键使用模板,快速填写内容,轻松发帖~
知道了
  • 为了保障您的信息安全,请勿上传您的敏感个人信息(如您的密码等信息)和您的敏感资产信息(如关键源代码、签名私钥、调试安装包、业务日志等信息),且您需自行承担由此产生的信息泄露等安全风险。
  • 如您发布的内容为转载内容,请注明内容来源。

我要发帖子

目录 收起
1 源码修改
2 内部原理
普通的处理方式
GCC全局寄存器处理方式
3 技术推广
4 附录
寄存器变量
全局寄存器变量
了解社区公约,与您携手共创和谐专业的开发者社区。