More Related Content Similar to "Развитие ветки PHP-7" (20) More from Badoo Development (20) "Развитие ветки PHP-7"1. Confidential - © All rights reserved. Zend Technologies, Inc.1
Copyright - © All rights reserved. Zend Technologies, Inc.
Развитие PHP 7.*
Dmitry Stogov
DevConf 2016, Москва
Principal Engineer at Zend Technologies
2. Copyright - © All rights reserved. Zend Technologies, Inc.2
Кто Я?
●
Работаю в ИТ с 1991
●
Первое знакомство с PHP в 2002
●
Автор Turck MMCache (eAccelerator)
●
Работаю в Zend Technologies с 2004
●
Сейчас ведущий инженер
●
Автор ext/soap и pecl/perl
●
Один из ведущих разработчиков Open Source PHP
●
Майнтейнер Zend OPcache
●
Лидер проекта PHPNG легшего в основу PHP 7
3. Copyright - © All rights reserved. Zend Technologies, Inc.3
Производительность PHP на синтетических тестах
0 2 4 6 8 10 12 14
12.68
12.54
4.68
4.2
2.91
2.18
2.03
1.92
0.78
0.56
0.38
bench.php [sec]
4.4
5.0 - Jul 2004
5.1 - Nov 2005
5.2 - Nov 2006
5.3 - Nov 2009
5.4 - Mar 2012
5.5 - Jun 2013
5.6 - Aug 2014
7.0.0 - Dec 2015
7.1 Jun 2016
HHVM-3.13.2
sec
PHP-7.1 еще на 25% быстрее PHP-7.0 но все еще медленнее HHVM
4. Copyright - © All rights reserved. Zend Technologies, Inc.4
Производительность PHP на реальных приложениях
0 50 100 150 200 250
54
51
56
67
76
91
93
101
232
235
206
WordPress-3.6.0 Home Page [req/sec]
4.4
5.0 - Jul 2004
5.1 - Nov 2005
5.2 - Nov 2006
5.3 - Nov 2009
5.4 - Mar 2012
5.5 - Jun 2013
5.6 - Aug 2014
7.0.0 - Dec 2015
7.1 Jun 2016
HHVM-3.13.2
req/sec
На реальных приложениях PHP-7.1 пока не дает существенного выигрыша!
5. Copyright - © All rights reserved. Zend Technologies, Inc.5
PHPNG (New Generation)
●
Проект получил свое развитие после попыток создания JIT для PHP
●
Рефакторинг (ни каких нововведений, 100% совместимость с PHP 5)
●
Основная цель — достичь нового уровня производительности и
заложить базу для будущих улучшений
●
Отделился от основной ветки PHP в январе 2014
●
Две недели ушло на то что-бы просто скомпилировать ядро
●
Еще через две недели заработал bench.php
●
Полтора месяца для обеспечения совместимости с Wordpress
●
Еще через месяц (к 9 Мая) мы открыли проект
●
В августе 2014 принят как основа для будущего PHP 7
6. Copyright - © All rights reserved. Zend Technologies, Inc.6
PHP 7.0
●
Было решено выпускать PHP 7 после PHP 5, пропустив PHP 6
●
GA релиз состоялся в декабре 2015
●
Сейчас доступен PHP-7.0.7
●
Возможность определять скалярные типы аргументов функций и
возвращаемых значений
●
Исключения вместо фатальных ошибок
●
Анонимный классы
●
Zero-cost assert()
●
Новые операторы и функции (<=>, ??)
●
Чистка неконсистентностей
7. Copyright - © All rights reserved. Zend Technologies, Inc.7
Badoo перешли на PHP 7.0 и сэкономили $1M
8. Copyright - © All rights reserved. Zend Technologies, Inc.8
Что дальше?
●
PHP 7.0
●
Оптимизация структур данных
●
PHP 7.1
●
Анализатор потоков данных
●
Вывод типов
●
Глобальный оптимизатор для байт-кода PHP
●
Оптимизация и Специализация интерпретатора
9. Copyright - © All rights reserved. Zend Technologies, Inc.9
zval
type_flags
value
type reserved
● IS_UNDEF
● IS_NULL
● IS_FALSE
● IS_TRUE
● IS_LONG
● IS_DOUBLE
● IS_STRING
● IS_ARRAY
● IS_OBJECT
● IS_RESOURCE
● IS_REFERENCE
● IS_INDIRECT
● IS_PTR
● IS_TYPE_CONSTANT
● IS_TYPE_REFCOUNTED
● IS_TYPE_COLLECTABLE
● IS_TYPE_COPYABLE
● IS_TYPE_IMMUTABLE
0 7 8 31 32 63
new type
old IS_BOOL
scalars
refcounted
new type
10. Copyright - © All rights reserved. Zend Technologies, Inc.10
zval (refcounted)
● IS_STRING
● IS_ARRAY
● IS_OBJECT
● IS_RESOURCE
● IS_REFERENCE
type_flags
value
type reserved
...
typerefcount flags gc_info
0 7 8 31 32 63
11. Copyright - © All rights reserved. Zend Technologies, Inc.11
zval (string)
● IS_STR_PERSISTENT
● IS_STR_INTERNED
● IS_STR_PERMANENTflags
value
type reserved
hash_value
typerefcount flags gc_info
len
val
...
0 7 8 31 32 63
12. Copyright - © All rights reserved. Zend Technologies, Inc.12
zval (array)
flags
value
type reserved
typerefcount flags gc_info
HashTable
● IS_ARRAY_IMMUTABLE
0 7 8 31 32 63
13. Copyright - © All rights reserved. Zend Technologies, Inc.13
zval (array) / HashTable
flags
value
type reserved
0 7 8 31 32 63
Bucket index N
...
Bucket index 0
key
hash_val
Bucket 0
val
...
key
hash_val
Bucket N
val
string, rc=1
«hello»
typerefcount flags gc_info
flags
arData
nTableMask
nNumUsed nNumOfElem
nNextFreeElement
nInternalPtrnTableSize
pDestructor
14. Copyright - © All rights reserved. Zend Technologies, Inc.14
HashTable (PHP 5.*)
nKeyLenght
hash_val
Bucket
pData
pDataPtr
pListNext
pListPrev
pNext
pPrev
arKey
pInternalPointer
nTableSize
nNextFreeElement
nTableMask
nNumOfElem
pListHead
pListTail
arBuckets
pDestructor
HashTable
nKeyLenght
hash_val
Bucket
pData
pDataPtr
pListNext
pListPrev
pNext
pPrev
arKey
type
value
zval
Bucket*
Bucket*
...
Bucket*
«hello»
15. Copyright - © All rights reserved. Zend Technologies, Inc.15
PHP 5.6 PHP 7
Memory Usage 428 MB 34 MB
Time 0.49 sec 0.06 sec
$a = array();
for ($i = 0; $i < 1000000; $i++) $a[$i] = array("hello");
echo memory_get_usage(true);
if (in array($color, array(“red”, “yellow”, “green”)) {
...
}
Immutable Arrays (Неизменяемые массивы)
16. Copyright - © All rights reserved. Zend Technologies, Inc.16
zval (object/PHP 7)
● IS_OBJ_DTOR_CALLED
● IS_OBJ_FREE_CALLED
● IS_OBJ_USE_GUARDS
● IS_OBJ_HAS_GUARDS
flags
value
type reserved
zend_class_entry *ce
typerefcount flags gc_info
zend_object_handlers *handlers
HashTable *properies
...
zval property_N
zval property1
HashTable *guards (optional)
0 7 8 31 32 63
17. Copyright - © All rights reserved. Zend Technologies, Inc.17
zval (reference)
flags
value
type reserved
typerefcount flags gc_info
zval val
0 7 8 31 32 63
18. Copyright - © All rights reserved. Zend Technologies, Inc.18
Компиляция PHP 7
<?php
$name = $_GET['name'];
echo “hello $namen”;
Lexer
Parser
Compiler
filename
zend_op_array
vars
scope
name
hello.php
opcodes
...
literals
arg_info
FETCH_R C0, V1
zend_op
ROPE_INIT C2,T1
ASSIGN $0,V2
FETCH_DIM_R V1,C1,V2
ROPE_ADD $0,T1
ECHO T1
ROPE_END C3,T1
RETURN C4
$name
zend_string
“_GET”
zval
“n”
“hello “
“name”
int(1)
AST
tokens
19. Copyright - © All rights reserved. Zend Technologies, Inc.19
Структуры Данных PHP 7 Времени Исполнения
current_execute_data
zend_executor_globals
scope (removed in 7.1)
..
func
zend_execute_data
called_scope (removed in 7.1)
zval* return_value
call
opline
symbol_table
prev_execute_data
run_time_cache
literals
zval This
...
zend_op_array
opcodes
...
literals
FETCH_R
zend_op
ROPE_INIT
ASSIGN
FETCH_DIM_R
ROPE_ADD
ECHO
ROPE_END
RETURN
“_GET”
zval
“name”
literals
$name
V2
V1 / T1
20. Copyright - © All rights reserved. Zend Technologies, Inc.20
Интерпретация PHP 7
register zend_execute_data *exexute_data
__asm__(«%r14»);
register zend_op *opline
__asm__(«%r15»);
void execute_ex(zend_execute_data *ex)
{
exexute_data = ex;
opline = exexcute_data->opline;
do {
opline->handler();
} while (opline);
}
ZEND_VM_HANDLER(1, ZEND_ADD,
CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
zval *op1, *op2, *result;
op1 = GET_OP1_ZVAL_PTR(BP_VAR_R);
op2 = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (Z_TYPE_P(op1)== IS_LONG) {
if (Z_TYPE_P(op2) == IS_LONG) {
result = EX_VAR(opline->result.var);
fast_long_add_function(result, op1, op2);
} else if (Z_TYPE_P(op2) == IS_DOUBLE) {
...
} else{
…
}
opline++;
}
21. Copyright - © All rights reserved. Zend Technologies, Inc.21
Интерпретация PHP 7
register zend_execute_data *exexute_data
__asm__(«%r14»);
register zend_op *opline
__asm__(«%r15»);
void execute_ex(zend_execute_data *ex)
{
exexute_data = ex;
opline = exexcute_data->opline;
do {
opline->handler();
} while (opline);
}
static void ZEND_ADD_SPEC_TMPVAR_CONST(void)
{
zval *op1, *op2, *result;
op1 = ZEND_CALL_VAR(execute_data, opline->op1.var);
op2 = execute_data->literals[opline->op2.num];
if (Z_TYPE_P(op1)== IS_LONG) {
if (Z_TYPE_P(op2) == IS_LONG) {
result = EX_VAR(opline->result.var);
fast_long_add_function(result, op1, op2);
} else if (Z_TYPE_P(op2) == IS_DOUBLE) {
...
} else{
…
}
opline++;
}
22. Copyright - © All rights reserved. Zend Technologies, Inc.22
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (zvals)
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
CALL FRAME
call
opline
prev_execute_data
current_execute_data
23. Copyright - © All rights reserved. Zend Technologies, Inc.23
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
...
...
...
SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
Arg1:
Arg2:
VM STACK (zvals)
CALL FRAME
opline
prev_execute_data
current_execute_data
CALL FRAME
call
prev_execute_data
call
opline
24. Copyright - © All rights reserved. Zend Technologies, Inc.24
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
VM STACK (zvals)
CALL FRAME
call
opline
prev_execute_data
current_execute_data
int(3)
...
...
Arg1:
Arg2:
CALL FRAME
call
opline
prev_execute_data
25. Copyright - © All rights reserved. Zend Technologies, Inc.25
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
int(5)
...
Arg1:
Arg2:
VM STACK (zvals)
CALL FRAME
call
opline
prev_execute_data
current_execute_data
CALL FRAME
call
opline
prev_execute_data
int(3)
26. Copyright - © All rights reserved. Zend Technologies, Inc.26
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
skip first 2 instructions
local variables already in-place
VM STACK (zvals)
CALL FRAME
opline
prev_execute_data
int(3)
...
CALL FRAME
call
opline
Arg2 $b:
Arg1 $a:
int(5)
call
prev_execute_data
current_execute_data
27. Copyright - © All rights reserved. Zend Technologies, Inc.27
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
VM STACK (zvals)
CALL FRAME
call
opline
prev_execute_data
current_execute_data
VM STACK (zvals)
CALL FRAME
call
opline
prev_execute_data
current_execute_data
int(3)
CALL FRAME
call
opline
prev_execute_data
int(5)
int(8)
Arg2 $b:
Arg1 $a:
28. Copyright - © All rights reserved. Zend Technologies, Inc.28
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
VM STACK (zvals)
CALL FRAME
call
opline
prev_execute_data
current_execute_data
int(3)
int(5)
int(8)
CALL FRAME
prev_execute_data
call
opline
Arg2 $b:
Arg1 $a:
29. Copyright - © All rights reserved. Zend Technologies, Inc.29
VM Calling Convention (PHP 7)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
...SEND_VAL 3
SEND_VAL 5
DO_FCALL
RETURN null
INIT_FCALL “foo”/2
VM STACK (zvals)
CALL FRAME
call
opline
prev_execute_data
current_execute_data
30. Copyright - © All rights reserved. Zend Technologies, Inc.30
Что дальше?
●
PHP 7.0
●
Оптимизация структур данных
●
PHP 7.1
●
Анализатор потоков данных
●
Вывод типов
●
Глобальный оптимизатор для байт-кода PHP
●
Оптимизация и Специализация интерпретатора
31. Copyright - © All rights reserved. Zend Technologies, Inc.31
PHP 7.1
●
Первый Alpha релиз в июне 2016
●
Feature Freeze в июле
●
GA релиз запланирован на ноябрь 2016
●
Nullable types - function foo(?Node $x): ?Node;
●
Void return type - function foo(): void;
●
Keys in list() - foreach ($points as list(«x»=>$x, «y»=>$y))
●
Class constants visibility - private const X = 42;
●
Negative string offsets - $a = “abcd”; var_dump($a[-2]);
●
Invalid numeric strings - 5 * “orange”
●
Closure::fromCallable()
32. Copyright - © All rights reserved. Zend Technologies, Inc.32
PHP 7.1 Optimizer (script)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
33. Copyright - © All rights reserved. Zend Technologies, Inc.33
PHP 7.1 Optimizer (bytecode)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ADD $sum, $i -> T2
ASSIGN $sum, T2
POST_INC $i -> T4
FREE T4
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
RETUTN null
34. Copyright - © All rights reserved. Zend Technologies, Inc.34
PHP 7.1 Optimizer (trivial optimization)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ADD $sum, $i -> T2
ASSIGN $sum, T2
POST_INC $i -> T4
FREE T4
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
RETUTN null
35. Copyright - © All rights reserved. Zend Technologies, Inc.35
PHP 7.1 Optimizer (trivial optimization)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum += $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
POST_INC $i -> T4
FREE T4
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
RETUTN null
36. Copyright - © All rights reserved. Zend Technologies, Inc.36
PHP 7.1 Optimizer (trivial optimization)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
POST_INC $i -> T4
FREE T4
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
RETUTN null
37. Copyright - © All rights reserved. Zend Technologies, Inc.37
PHP 7.1 Optimizer (trivial optimization)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; ++$i) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
PRE_INC $i
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
RETUTN null
38. Copyright - © All rights reserved. Zend Technologies, Inc.38
PHP 7.1 Optimizer (trivial optimization)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
PRE_INC $i
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
RETUTN null
39. Copyright - © All rights reserved. Zend Technologies, Inc.39
PHP 7.1 Optimizer (trivial optimization)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
PRE_INC $i
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
40. Copyright - © All rights reserved. Zend Technologies, Inc.40
PHP 7.1 Optimizer (Control Flow Graph)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
PRE_INC $i
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
41. Copyright - © All rights reserved. Zend Technologies, Inc.41
PHP 7.1 Optimizer (Control Flow Graph)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
PRE_INC $i
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
42. Copyright - © All rights reserved. Zend Technologies, Inc.42
PHP 7.1 Optimizer (Control Flow Graph)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
PRE_INC $i
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
43. Copyright - © All rights reserved. Zend Technologies, Inc.43
PHP 7.1 Optimizer (Control Flow Graph)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ASSIGN_ADD $sum, $i
PRE_INC $i
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
44. Copyright - © All rights reserved. Zend Technologies, Inc.44
PHP 7.1 Optimizer (Static Single Assignmnt Form)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $1.sum, 0
ASSIGN $2.i, 0
JMP L1
L0:
ASSIGN_ADD $?.sum → $3.sum, $?.i
PRE_INC $?.i → $4.i
L1:
IS_SMALLER $?.i, 100 -> T5
JMPNZ T5, L0
RETRUN $?.sum
45. Copyright - © All rights reserved. Zend Technologies, Inc.45
PHP 7.1 Optimizer (Static Single Assignmnt Form)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $1.sum, 0
ASSIGN $2.i, 0
JMP L1
L0:
ASSIGN_ADD $?.sum → $3.sum, $?.i
PRE_INC $?.i → $4.i
$5.sum = Phi($1.sum, $3.sum)
$6.i = Phi($2.i, $4.i)
IS_SMALLER $?.i, 100 -> T5
JMPNZ T5, L0
RETRUN $?.sum
46. Copyright - © All rights reserved. Zend Technologies, Inc.46
PHP 7.1 Optimizer (Static Single Assignmnt Form)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $1.sum, 0
ASSIGN $2.i, 0
JMP L1
L0:
ASSIGN_ADD $5.sum → $3.sum, $6.i
PRE_INC $6.i → $4.i
$5.sum = Phi($1.sum, $3.sum)
$6.i = Phi($2.i, $4.i)
IS_SMALLER $6.i, 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum
47. Copyright - © All rights reserved. Zend Technologies, Inc.47
PHP 7.1 Optimizer (Extended Static Single Assignmnt Form)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
ASSIGN $1.sum, 0
ASSIGN $2.i, 0
JMP L1
$7.i = Pi($6.i & RANGE[--..99])
ASSIGN_ADD $5.sum → $3.sum, $7.i
PRE_INC $7.i → $4.i
$5.sum = Phi($1.sum, $3.sum)
$6.i = Phi($2.i, $4.i)
IS_SMALLER $6.i, 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum
48. Copyright - © All rights reserved. Zend Technologies, Inc.48
PHP 7.1 Optimizer (Extended Static Single Assignmnt Form)
ASSIGN $1.sum, 0
ASSIGN $2.i, 0
JMP L1
$7.i = Pi($6.i & RANGE[--..99])
ASSIGN_ADD $5.sum → $3.sum, $7.i
PRE_INC $7.i → $4.i
$5.sum = Phi($1.sum, $3.sum)
$6.i = Phi($2.i, $4.i)
IS_SMALLER $6.i, 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum
49. Copyright - © All rights reserved. Zend Technologies, Inc.49
PHP 7.1 Optimizer (Type Propagation)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i = Pi($6.i & RANGE[--..99])
ASSIGN_ADD $5.sum → $3.sum, $7.i
PRE_INC $7.i → $4.i
$5.sum = Phi($1.sum, $3.sum)
$6.i = Phi($2.i, $4.i)
IS_SMALLER $6.i, 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum
50. Copyright - © All rights reserved. Zend Technologies, Inc.50
PHP 7.1 Optimizer (Type Propagation)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i = Pi($6.i & RANGE[--..99])
ASSIGN_ADD $5.sum → $3.sum, $7.i
PRE_INC $7.i → $4.i
$5.sum = Phi($1.sum [long], $3.sum)
$6.i = Phi($2.i [long], $4.i)
IS_SMALLER $6.i, 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum
51. Copyright - © All rights reserved. Zend Technologies, Inc.51
PHP 7.1 Optimizer (Type Propagation)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i = Pi($6.i & RANGE[--..99])
ASSIGN_ADD $5.sum → $3.sum, $7.i
PRE_INC $7.i → $4.i
$5.sum [long] = Phi($1.sum [long], $3.sum)
$6.i [long] = Phi($2.i [long], $4.i)
IS_SMALLER $6.i, 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum
52. Copyright - © All rights reserved. Zend Technologies, Inc.52
PHP 7.1 Optimizer (Type Propagation)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ASSIGN_ADD $5.sum [long] → $3.sum [?], $7.i [long]
PRE_INC $7.i [long] → $4.i [?]
$5.sum [long] = Phi($1.sum [long], $3.sum [?])
$6.i [long] = Phi($2.i [long], $4.i [?])
IS_SMALLER $6.i [long], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long]
53. Copyright - © All rights reserved. Zend Technologies, Inc.53
PHP 7.1 Optimizer (Type Propagation)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ASSIGN_ADD $5.sum [long] → $3.sum [long, double], $7.i [long]
PRE_INC $7.i [long] → $4.i [long, double]
$5.sum [long] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long] = Phi($2.i [long], $4.i [long, double])
IS_SMALLER $6.i [long], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long]
54. Copyright - © All rights reserved. Zend Technologies, Inc.54
PHP 7.1 Optimizer (Type Propagation)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long, double] = Pi($6.i [long, double] & RANGE[--..99])
ASSIGN_ADD $5.sum [long, double] → $3.sum [long, double], $7.i [long, double]
PRE_INC $7.i [long, double] → $4.i [long, double]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long, double] = Phi($2.i [long], $4.i [long, double])
IS_SMALLER $6.i [long, double], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long, double]
55. Copyright - © All rights reserved. Zend Technologies, Inc.55
PHP 7.1 Optimizer (Range Propagation)
ASSIGN $1.sum [0..0], 0
ASSIGN $2.i [0..0], 0
JMP L1
$7.i = Pi($6.i & RANGE[--..99])
ASSIGN_ADD $5.sum → $3.sum, $7.i
PRE_INC $7.i → $4.i
$5.sum = Phi($1.sum, $3.sum)
$6.i = Phi($2.i, $4.i)
IS_SMALLER $6.i, 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum
56. Copyright - © All rights reserved. Zend Technologies, Inc.56
PHP 7.1 Optimizer (Range Propagation)
ASSIGN $1.sum [0..0], 0
ASSIGN $2.i [0..0], 0
JMP L1
$7.i [0..0] = Pi($6.i [0..0] & RANGE[--..99])
ASSIGN_ADD $5.sum [0..0] → $3.sum [?], $7.i [0..0]
PRE_INC $7.i [0..0] → $4.i [?]
$5.sum [0..0] = Phi($1.sum [0..0], $3.sum [?])
$6.i [0..0] = Phi($2.i [0..0], $4.i [?])
IS_SMALLER $6.i [0..0], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [0..0]
57. Copyright - © All rights reserved. Zend Technologies, Inc.57
PHP 7.1 Optimizer (Range Propagation)
ASSIGN $1.sum [0..0], 0
ASSIGN $2.i [0..0], 0
JMP L1
$7.i [0..0] = Pi($6.i [0..0] & RANGE[--..99])
ASSIGN_ADD $5.sum [0..0] → $3.sum [0..0], $7.i [0..0]
PRE_INC $7.i [0..0] → $4.i [1..1]
$5.sum [0..0] = Phi($1.sum [0..0], $3.sum [0..0])
$6.i [0..0] = Phi($2.i [0..0], $4.i [1..1])
IS_SMALLER $6.i [0..0], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [0..0]
58. Copyright - © All rights reserved. Zend Technologies, Inc.58
PHP 7.1 Optimizer (Range Propagation)
ASSIGN $1.sum [0..0], 0
ASSIGN $2.i [0..0], 0
JMP L1
$7.i [0..0] = Pi($6.i [0..++] & RANGE[--..99])
ASSIGN_ADD $5.sum [0..0] → $3.sum [0..0], $7.i [0..0]
PRE_INC $7.i [0..0] → $4.i [1..1]
$5.sum [0..0] = Phi($1.sum [0..0], $3.sum [0..0])
$6.i [0..++] = Phi($2.i [0..0], $4.i [1..1])
IS_SMALLER $6.i [0..++], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [0..0]
59. Copyright - © All rights reserved. Zend Technologies, Inc.59
PHP 7.1 Optimizer (Range Propagation)
ASSIGN $1.sum [0..0], 0
ASSIGN $2.i [0..0], 0
JMP L1
$7.i [0..99] = Pi($6.i [0..++] & RANGE[--..99])
ASSIGN_ADD $5.sum [0..0] → $3.sum [0..0], $7.i [0..99]
PRE_INC $7.i [0..99] → $4.i [1..1]
$5.sum [0..0] = Phi($1.sum [0..0], $3.sum [0..0])
$6.i [0..++] = Phi($2.i [0..0], $4.i [1..1])
IS_SMALLER $6.i [0..++], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [0..0]
60. Copyright - © All rights reserved. Zend Technologies, Inc.60
PHP 7.1 Optimizer (Range Propagation)
ASSIGN $1.sum [0..0], 0
ASSIGN $2.i [0..0], 0
JMP L1
$7.i [0..99] = Pi($6.i [0..++] & RANGE[--..99])
ASSIGN_ADD $5.sum [0..0] → $3.sum [0..100], $7.i [0..99]
PRE_INC $7.i [0..99] → $4.i [1..100]
$5.sum [0..0] = Phi($1.sum [0..0], $3.sum [0..100])
$6.i [0..++] = Phi($2.i [0..0], $4.i [1..100])
IS_SMALLER $6.i [0..++], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [0..0]
61. Copyright - © All rights reserved. Zend Technologies, Inc.61
PHP 7.1 Optimizer (Range Propagation)
ASSIGN $1.sum [0..0], 0
ASSIGN $2.i [0..0], 0
JMP L1
$7.i [0..99] = Pi($6.i [0..++] & RANGE[--..99])
ASSIGN_ADD $5.sum [0..++] → $3.sum [0..++], $7.i [0..99]
PRE_INC $7.i [0..99] → $4.i [1..100]
$5.sum [0..++] = Phi($1.sum [0..0], $3.sum [0..++])
$6.i [0..++] = Phi($2.i [0..0], $4.i [1..100])
IS_SMALLER $6.i [0..++], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [0..++]
62. Copyright - © All rights reserved. Zend Technologies, Inc.62
PHP 7.1 Optimizer (Range Propagation - narrowing)
ASSIGN $1.sum [0..0], 0
ASSIGN $2.i [0..0], 0
JMP L1
$7.i [0..99] = Pi($6.i [0..100] & RANGE[--..99])
ASSIGN_ADD $5.sum [0..++] → $3.sum [0..++], $7.i [0..99]
PRE_INC $7.i [0..99] → $4.i [1..100]
$5.sum [0..++] = Phi($1.sum [0..0], $3.sum [0..++])
$6.i [0..100] = Phi($2.i [0..0], $4.i [1..100])
IS_SMALLER $6.i [0..100], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [0..++]
63. Copyright - © All rights reserved. Zend Technologies, Inc.63
PHP 7.1 Optimizer (Range + Type Propagation)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long, double] = Pi($6.i [long, double] & RANGE[--..99])
ASSIGN_ADD $5.sum [long, double] → $3.sum [long, double], $7.i [long, double]
PRE_INC $7.i [long, double] → $4.i [long, double]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long, double] = Phi($2.i [long], $4.i [long, double])
IS_SMALLER $6.i [long, double], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long, double]
64. Copyright - © All rights reserved. Zend Technologies, Inc.64
PHP 7.1 Optimizer (Range + Type Propagation)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ASSIGN_ADD $5.sum [long, double] → $3.sum [long, double], $7.i [long]
PRE_INC $7.i [long] [0..99] → $4.i [long] [1..100]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long] = Phi($2.i [long], $4.i [long])
IS_SMALLER $6.i [long], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long, double]
65. Copyright - © All rights reserved. Zend Technologies, Inc.65
PHP 7.1 Optimizer (Optimization)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ASSIGN_ADD $5.sum [long, double] → $3.sum [long, double], $7.i [long]
PRE_INC $7.i [long] [0..99] → $4.i [long] [1..100]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long] = Phi($2.i [long], $4.i [long])
IS_SMALLER $6.i [long], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long, double]
66. Copyright - © All rights reserved. Zend Technologies, Inc.66
PHP 7.1 Optimizer (Optimization)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ADD $3.sum [long, double], $7.i [long] → $5.sum [long, double]
PRE_INC $7.i [long] [0..99] → $4.i [long] [1..100]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long] = Phi($2.i [long], $4.i [long])
IS_SMALLER $6.i [long], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long, double]
67. Copyright - © All rights reserved. Zend Technologies, Inc.67
PHP 7.1 Optimizer (Optimization)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ADD $3.sum [long, double], $7.i [long] → $5.sum [long, double]
PRE_INC $7.i [long] [0..99] → $4.i [long] [1..100]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long] = Phi($2.i [long], $4.i [long])
IS_SMALLER $6.i [long], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long, double]
68. Copyright - © All rights reserved. Zend Technologies, Inc.68
PHP 7.1 Optimizer (Optimization)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ADD $3.sum [long, double], $7.i [long] → $5.sum [long, double]
PRE_INC_LONG_NOOVERFLOW $7.i [long] [0..99] → $4.i [long] [1..100]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long] = Phi($2.i [long], $4.i [long])
IS_SMALLER $6.i [long], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long, double]
69. Copyright - © All rights reserved. Zend Technologies, Inc.69
PHP 7.1 Optimizer (Optimization)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ADD $3.sum [long, double], $7.i [long] → $5.sum [long, double]
PRE_INC_LONG_NOOVERFLOW $7.i [long] [0..99] → $4.i [long] [1..100]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long] = Phi($2.i [long], $4.i [long])
IS_SMALLER $6.i [long], 100 -> T5
JMPNZ T5, L0
RETRUN $5.sum [long, double]
70. Copyright - © All rights reserved. Zend Technologies, Inc.70
PHP 7.1 Optimizer (Optimization)
ASSIGN $1.sum [long], 0
ASSIGN $2.i [long], 0
JMP L1
$7.i [long] = Pi($6.i [long] & RANGE[--..99])
ADD $3.sum [long, double], $7.i [long] → $5.sum [long, double]
PRE_INC_LONG_NOOVERFLOW $7.i [long] [0..99] → $4.i [long] [1..100]
$5.sum [long, double] = Phi($1.sum [long], $3.sum [long, double])
$6.i [long] = Phi($2.i [long], $4.i [long])
IS_SMALLER_LONG_JMPNZ $6.i [long], 100, L0
RETRUN $5.sum [long, double]
71. Copyright - © All rights reserved. Zend Technologies, Inc.71
PHP 7.1 Optimizer (SSA deconstruction)
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ADD $sum, $i → $sum
PRE_INC_LONG_NOOVERFLOW $i
L1:
IS_SMALLER_LONG_JMPNZ $i, 100, L0
RETRUN $sum
ASSIGN $sum, 0
ASSIGN $i, 0
JMP L1
L0:
ADD $sum, $i -> T2
ASSIGN $sum, T2
POST_INC $i -> T4
FREE T4
L1:
IS_SMALLER $i, 100 -> T5
JMPNZ T5, L0
RETRUN $sum
RETUTN null
72. Copyright - © All rights reserved. Zend Technologies, Inc.72
PHP 7.1 Specialized Handlers
void PRE_INC_HANDLER()
{
if (Z_TYPE_P(op1) != IS_LONG) {
… // not integer
} else {
Z_LVAL_P(op1)++;
if (OVERFLOW) {
… // overflow
}
}
CHECK_EXCEPTION();
NEXT_OPCODE();
}
void
PRE_INC_HANDLER_LONG_NO_OVERFLOW()
{
Z_LVAL_P(op1)++;
NEXT_OPCODE();
}
mov 0x4(%IP), %eax // get op1 offset
incl (%FP, %eax) // increment
add 0x1c, %IP // next opcode
ret
73. Copyright - © All rights reserved. Zend Technologies, Inc.73
Что дальше?
●
PHP 7.0
●
Оптимизация структур данных
●
PHP 7.1
●
Анализатор потоков данных
●
Вывод типов
●
Глобальный оптимизатор для байт-кода PHP
●
Оптимизация и Специализация интерпретатора
●
PHP 7.2
●
JIT?
74. Copyright - © All rights reserved. Zend Technologies, Inc.74
The Computer Language Benchmarks Game (Mandelbrot)
GCC-5.3 -O3
PHP/llvm-jit
LuaJit-2.1.0-beta2
JavaScriptCore-1.12.3
V8-3.14.5.10
HHVM-3.13.2 (--count=2)
SpiderMonrey-1.8.5
PyPy-4.0.1
Java (openjdk-1.8)
PHP-7.1.0-dev
LuaJit-2.1.0-beta2 (-j off)
JavaScriptCore-1.12.3 (LLint)
PHP-7.0.7
Java (openjdk-1.8 -Xint)
Lua-5.3.2
PHP-5.6.20
Ruby-2.2.5
Python-2.7.11
HHVM-3.13.2 (Jit=false)
Perl-5.22.1
0 0.5 1 1.5 2 2.5
0.011
0.011
0.013
0.014
0.016
0.019
0.027
0.030
0.046
0.092
0.098
0.190
0.227
0.243
0.300
0.363
0.609
0.940
1.036
2.063
sec
Самый быстрый интерпретатор,
все что быстрее с JIT.
В перспективе - быстрее некуда :)
75. Confidential - © All rights reserved. Zend Technologies, Inc.75
Вопросы?
Dmitry Stogov
Principal Engineer at Zend Technologies
@dstogov
dmitry@zend.com
www.zend.com