澳门新葡亰信誉平台游戏HHVM 3.0 发布,执行 PHP 的虚拟机

by admin on 2020年4月22日

2013年夏天,Facebook工程师开始对HHVM JIT编译器进行重大的重新设计,这次重新设计使得Facebook
Web服务器CPU的使用率整体降低了15%。Facebook工程师Guilherme
Ottoni最近描述了Facebook如何在JIT编译器中利用性能分析引导优化(PGO)技术达到这一效果。

HHVM

HHVM是什么?

HHVM(HipHop
VM)是Fackbook推出用于在执行PHP代码的虚拟机,是一个PHP的JIT编译器,具有产生快速代码和及时编译的优点。

HHVM能干什么?

HHVM脚本主要应用服务器端脚本和命令行脚本两大领域,专注于服务器端脚本,如收集表单数据、生成动态页面、发送接受COOKIE等。

澳门新葡亰信誉平台游戏,HHVM为什么比ZendEngine快?

HHVM是Facebook开发的高性能PHP虚拟机,宣称比官方Zend快9倍。

PHP使用的Zend虚拟机(VM),首先会先将PHP代码编译成二进制指令opcode,然后逐条执行,每条opcode指令都对应一个C函数。对于PHP的用户函数、运行时局部变量、常量会存在一个Hashtable中。

执行一次C函数的开销

  • 参数的入栈出栈
  • CPU寄存器状态保存

例如:在PHP中执行1000w次累加

<?php
$sum = 0;
// 发生1000w次C函数调用
for($i=0; $i<10000000; $i++){
  $sum += $i;
}

若编译为机器码情况是什么样的呢?

主频2.0GHZ的CPU每秒执行20亿次指令,函数调用则1秒只能运行1000W次。

因此,编译为机器码执行语言如C、C++、Golang…,或拥有JIT的语言如Java、NodeJS、LuaJIT、HHVM…,单从指令执行角度上看至少比PHP快几十倍。

对于字符串处理、JSON编码解码、iconv编码解码、数组操作等,
PHP比C++、Java慢吗?

在PHP中此类操作都是C扩展函数完成的,性能与编译型语言一致。

PHP到底比编译型语言慢的原因在哪里呢?

PHP代码中用户函数、类、对象操作等。

运算密集型 vs IO密集型

运算密集型程序指的是需大量执行内存复制操作、循环、运行指令等,瓶颈在CPU上,提升性能的解决方案就是提升CPU硬件配置、改进算法、提升语言/工具的执行性能。对于此类程序,PHP性能问题很明显,执行相同的逻辑,比C/C++慢几十倍甚至百倍,这是不可接受的。

IO密集型程序瓶颈在IO等待,例如HTTP请求执行100ms后返回,其中90ms查询数据库,8ms读写文件,
那么无论C/C++还是PHP,请求响应时间总是100ms左右,语言性能优化只有2ms的空间。

如何优化PHP呢

  • PHP语言层面优化
  • 优化PHP官方实现ZendEngine
  • 将PHP编译为其他语言字节码(bytecode),借助于其他语言虚拟机来运行。
  • 将PHP转成C/C++,编译成本地代码。
  • 开发更快的PHP虚拟机

Zend的执行过程可分为两个环节

  • 将PHP编译为opcode
  • 执行opcode

优化opcode可编码重复解析PHP与静态编译优化,由于PHP的动态性,这种优化方式是有局限,乐观估计可提升20%的性能。

优化opcode架构本身,工作量大投入产生比不高。

优化opcode执行,Zend解释器interpreter在读到opcode后会根据不同opcode调用不同函数(switch),在函数中执行语言相关的操作。优化空间不大。

优化Zend执行性能,对于函数调用的开销,通过inline
threading来优化,其原理如C中的inline关键字。

更快的虚拟机

HHVM 为什么更快,原因是JIT。

JIT操作本身是耗时的,对于简单程序或许比interpreter慢。HHVM的发展就是不断优化、优化、在优化。

澳门新葡亰信誉平台游戏 1

HHVM是如何超过HPHPc

什么是JIT,如何实现一个JIT?

动态语言中基本都会有一个eval(),作用是传入一段字符串来执行。JIT做着类似的事,不过它要拼接的不是字符串,而是不同平台下的机器码,然后执行。在JIT中更重要的优化是根据类型来生成特定的指令,从而减少指令数量和条件判断。

类型推导

JIT的关键是猜测类型,变量的类型要是老是变就很难优化。HHVM工程师考虑在PHP语法上做手脚,加上类型的支持,推出Hack。

<?hh
class Point
{
  // 使用静态类型可让HHVM更好的优化性能,不过这也意味着和PHP语法不兼容。
  public float $x,$y;
  public function __construct(float $x, float $y)
  {
    $this->x = $x;
    $this->y = $y;
  }
}

HHVM提升PHP执行性能

HHVM生成和执行PHP的在中间字节码,执行时通过JIT(Just In
Time即时编译,软件优化技术,指在运行时才会去编译字节码为机器码)转换为机器码执行。JIT将大量重复执行的字节码在运行时编译为机器码,达到提高执行效率的目的。通常触发JIT的条件是代码或函数被多次重复调用。

什么是字节码?

澳门新葡亰信誉平台游戏 2

字节码

ZendEngine做法是先编译为opcode,逐条执行,每条指令对应的是C语言级别的函数。

HHVM服务器最开始的少数请求会比其余的慢,因为它必须在执行PHP和Hack代码之前将它们编译成机器码,这个效果是非常明显的,所以你不应当立即把一个新设置的HHVM服务器应用到生产环境中。你应该先发送一些人工模拟的请求到这个HHVM服务器上,对它进行热身。
事实上,服务器启动的时候,并不会编译任何代码。初始的请求就是在HHVM的字节码解释器下运行的。原理就是:对于一个web服务器来说,最初的几个请求是不寻常的。在这个期间,开始了初始化,还对缓存进行填充等等。对这些代码路径的编译对整体性能的表现是非常糟糕的,因为一旦对服务器进行了预热,这些过程是不会被经常调用的。HHVM还利用这些请求,来收集一些代码所用到的数据类型分析的工作。所以它可以稍后更加有效地进行编译。你可以使用选项
hhvm.jit_profile_interp_requests 来调整这个门槛。
对于发送预热请求,颗通过命令行或其它类似的地方,简单地使用 curl
这个命令功能。为了得到最好的结果:
使用你希望在产品中看到的,能够代表最常见的请求的混合集合。例如,如果你期待所有对这个产品的请求中的40%都是到达
index.php 的,那么你的 40% 的预热请求都 应该是到 index.php 的请求。
避免并行发送多个预热请求,若你真的并行发送了多个请求,那么并不会出现什么问题。单对于JIT编译器来说,若没有同时工作在多个请求上的话,它往往能够生成更好的代码。
最终,你最好有个进程脚本用于服务器热身,这样的话,颗在命令行里仅仅执行一个命令就可以做到热身了。但是在最初期的时候,你还需要一些人工的参与,要实际计算出用于热身的请求数量是非常微妙的,
这主要取决于你的程序本身。

HHVM 详细介绍

性能分析引导优化技术主要采用运行时分析,例如,识别出更频繁执行的代码,以改进代码的生成。由于编译器和运行时环境的集成特性,PGO更适合集成到动态编译器和JIT编译器中。

HipHop
VM(HHVM)是Facebook推出的用来执行PHP代码的虚拟机,它是一个PHP的JIT(Just-In-
Time)编译器,同时具有产生快速代码和即时编译的优点。

Facebook工程师专注于两个主要的目标:利用性能分析的信息优化编译时作出的决策,以帮助编译器识别更大的专用类型编译区域(即可以为给定的已知类型生成的代码进行优化的区域),从而避免类型检查的开销。为了实现这一点,HHVM
JIT编译器必须学习如何转换任意代码区域,而不仅仅是tracelet,tracelet是非常基础的可以独立转换成机器代码的专用类型块。Tracelet不会任意增长,因为它的定义是:当无法确定块的输入类型或者当JIT编译器不能确定分支的方向时,tracelet就会结束。

Facebook表示,HHVM将替代HPHPi,用于所有的PHP执行。根据
Facebook透漏,HHVM在速度方面获得了显著改进,比目前使用的PHP解释器快60%,而使用内存减少90%。

Facebook工程师概括tracelet采取的第一步是,基于性能分析信息将其中的几个组合在一起。通过这样做,可以减少不同tracelet进入和退出的开销,并且实现更高级的cross-tracelet优化,例如提升循环不变式计算到循环外。

Facebook于12年十二月初发布了一个博文,宣布他们的解释型PHP运行环境HHVM(HipHop
VM)已经达到甚至超过了编译型PHP运行环境HipHop的运行速度。

澳门新葡亰信誉平台游戏 3

HHVM是在HPHPc的基础上构建,它会将PHP代码转换成高级别的字节码(一种中间语言),在运行时即时(JIT)编译器会将这些字节码翻译成机器码。
下面是一些关于字节码、机器码和即时(JIT)编译器的概念,快速的浏览以下概念,可以清楚这些概念在HHVM所处的角色。
字节码:是一种人类无法阅读的代码,专门用来给编译器高效执行的。当HHVM首次加载项目时,它会将所有的PHP代码转换成字节码;字节码的生成是与平台无关的。
机器码:是一系列供CPU执行的指令。用过汇编的都应该清楚机器码,估计没人喜欢用汇编编程。通过编译器就可以把汇编转成机器码,然后供CPU处理。
JIT(即时)编译器:即时编译是种软件优化技术,指在运行时才会去编译字节码。字节码会存放在内存中,然后JIT编译器会根据需要加载并编译所涉的字节码。
通过以上技术,HipHop和HHVM获得了性能的提升。
最近,HHVM几乎已经完全支持PHP
5.4了,但还是有不少bug,所以不是所有应用程序都可以运行。因此,Facebook准备让最流行的20个开源PHP项目能够运行在HHVM上。第一个已经支持的项目就是Wordpress

在基本的tracelet外构建更大的区域具有不违反现有JIT优化器和后端中任何假设的优点,这些假设是紧密围绕这一概念设计的。在第二个阶段,Facebook工程师开始重新设计这些组件,以便能够处理具有任意控制流的区域。这一努力在2015年春天完成了,通过将CPU使用率降低15%,显著提高了JIT编译器的性能,相比第一阶段的改进提升了两倍。

查看英文原文:How Facebook Redesigned the HHVM JIT Compiler for
Performance

来自:InfoQ

文章转载自:开源中国社区 []    

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图