SlideShare a Scribd company logo
1 of 95
Download to read offline
Confidential - © All rights reserved. Zend Technologies, Inc.1
Copyright - © All rights reserved. Zend Technologies, Inc.
Как мы сделали PHP 7 в два раза быстрее.
Дмитрий Стогов
HighLoad++ 2016, Москва
Principal Engineer at Zend Technologies
Copyright - © All rights reserved. Zend Technologies, Inc.2
Кто Я?
●
Познакомился с программированием в 1984
●
Работаю в ИТ с 1991
●
Первое знакомство с PHP в 2002
●
Автор Turck MMCache для PHP (eAccelerator)
●
Работаю в Zend Technologies с 2004
●
Сейчас ведущий инженер
●
Автор ext/soap и pecl/perl
●
Один из ведущих разработчиков Open Source PHP
●
Майнтейнер Zend OPcache
●
Лидер проекта PHPNG, легшего в основу PHP 7
●
Лидер разработки JIT для PHP
Copyright - © All rights reserved. Zend Technologies, Inc.3
PHP – Personal Home Page
●
Инструмент для создания персональных веб-страниц
●
Первый релиз PHP/FI 2.0 от Rasmus Lerdorf 8 июня 1995
●
В 1998 Andi Gutmans и Zeev Suraski выпустили PHP 3
●
PHP 4, основанный на Zend Engine, вышел в 2000
●
PHP 5 с переработанной ООП моделью вышел в 2004
●
ZendFramework в 2007
●
Сегодня более 70% сайтов интернета используют PHP
●
C 2010 Facebook работает над альтернативной реализацией – HHVM
●
В декабре 2015 вышел PHP 7
●
В ноябре 2016 должен выйти PHP 7.1
Copyright - © All rights reserved. Zend Technologies, Inc.4
Производительность PHP на синтетических тестах
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 - Dec 2015
7.1 - Oct 2016
HHVM-3.15.2
12.68
12.54
4.68
4.20
2.91
2.18
2.03
1.92
0.78
0.50
0.38
bench.php [sec] (чем меньше, тем лучше)
sec
PHP-7.1 еще на треть быстрее PHP-7.0, но все еще медленнее HHVM (на тестах!)
Copyright - © All rights reserved. Zend Technologies, Inc.5
Производительность PHP на реальных приложениях
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 - Dec 2015
7.1 - Oct 2016
HHVM-3.15.2
62
58
64
77
86
105
108
114
298
321
313
WordPress-3.6 Home Page [req/sec] (чем больше, тем лучше)
sec
Copyright - © All rights reserved. Zend Technologies, Inc.6
Блуждание в трех соснах (около JIT)
●
Почти два года потрачено на прототип JIT для PHP-5.5
●
Ускорение для bench.php в 10 раз
●
Ускорения для Wordpress нет (при компиляции в несколько минут)
Выводы:
●
Хороший код возможен при правильном предсказании типов
●
Предсказание типов в реальных приложениях работает плохо
●
Использование совместимых с PHP структур данных делает
генерируемый код неэффективным
Copyright - © All rights reserved. Zend Technologies, Inc.7
Что же тормозит? (WordPress/PHP 5.6)
Copyright - © All rights reserved. Zend Technologies, Inc.8
PHPNG (New Generation)
●
Проект получил свое развитие после попыток создания JIT для PHP
●
Рефакторинг (никаких нововведений, 100% совместимость с PHP 5)
●
Основная цель — достичь нового уровня производительности и
заложить базу для будущих улучшений
●
Отделился от основной ветки PHP в январе 2014
●
Две недели ушло на то, чтобы просто скомпилировать ядро
●
Еще через две недели заработал bench.php
●
Полтора месяца для обеспечения совместимости с Wordpress
●
Еще через месяц (к 9 Мая) мы открыли проект
●
В августе 2014 принят как основа для будущего PHP 7
Copyright - © All rights reserved. Zend Technologies, Inc.9
PHP 7.0
●
Было решено выпускать PHP 7 после PHP 5, пропустив PHP 6
●
GA релиз состоялся в декабре 2015
●
Сейчас доступен PHP-7.0.7
●
Возможность определять скалярные типы аргументов функций и
возвращаемых значений
●
Исключения вместо фатальных ошибок
●
Анонимные классы
●
Zero-cost assert()
●
Новые операторы и функции (<=>, ??)
●
Чистка неконсистентностей
Copyright - © All rights reserved. Zend Technologies, Inc.10
zval (PHP 5)
typedef struct _zval_struct {
union {
long lval;
double dval;
struct {
char *val;
Int len;
} str;
HashTable *ht;
struct {
zend_object_handle handle;
zend_object_handlers *handlers;
} obj;
} value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
sizeof(zval) == 24
$a = 1; $b = $a; $c = «hello»; $d = $c;
$b
$c
$a
$d
VM STACK (pointers to zvals) HEAP
string( ), rc=2
int(1), rc=2
«hello»
● read type - 2 CPU instructions
● read int value - 2 CPU instructions
● read string value - 3 CPU instructions
Copyright - © All rights reserved. Zend Technologies, Inc.11
zval (PHP 5 PHP 7)→
typedef struct _zval_struct {
union {
long lval;
double dval;
struct {
char *val;
int len;
} str;
HashTable *ht;
struct {
zend_object_handle handle;
zend_object_handlers *handlers;
} obj;
} value;
zend_uint refcount;
zend_uchar type;
zend_uchar is_ref;
} zval;
sizeof(zval) == 24
typedef struct _zval_struct {
union {
zend_long lval;
double dval;
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zval *zv;
void *ptr;
} value;
union {
struct {
zend_uchar type;
zend_uchar type_flags;
} v;
zend_uint type_info;
};
uint32_t reserved;
} zval;
sizeof(zval) == 16
new
Copyright - © All rights reserved. Zend Technologies, Inc.12
zval (PHP 5 PHP 7)→
● read type - 1 CPU instruction
● read int value - 1 CPU instruction
● read string value - 2 CPU instructions
$b
$c
$a
$d
int(1)
string( )
int(1)
string( )
VM STACK (zvals) HEAP
string, rc=2
«hello»
$a = 1; $b = $a; $c = «hello»; $d = $c;
$b
$c
$a
$d
VM STACK (pointers to zvals) HEAP
string( ), rc=2
int(1), rc=2
«hello»
● read type - 2 CPU instructions
● read int value - 2 CPU instructions
● read string value - 3 CPU instructions
Copyright - © All rights reserved. Zend Technologies, Inc.13
zval (PHP 5 PHP 7) Copy On Write→
● no CoW for scalars – few instructions
$b
$c
$a
$d
int(2)
string( )
int(1)
string( )
VM STACK (zvals) HEAP
string, rc=2
«hello»
$a = 1; $b = $a; $c = «hello»; $d = $c; $b = 2;
$b
$c
$a
$d
VM STACK (pointers to zvals) HEAP
string( ), rc=2
int(1), rc=1
«hello»
● CoW - hundreds CPU instructions
int(2), rc=1
Copyright - © All rights reserved. Zend Technologies, Inc.14
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
Copyright - © All rights reserved. Zend Technologies, Inc.15
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
Copyright - © All rights reserved. Zend Technologies, Inc.16
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
Copyright - © All rights reserved. Zend Technologies, Inc.17
zval (array)
flags
value
type reserved
typerefcount flags gc_info
HashTable
● IS_ARRAY_IMMUTABLE
0 7 8 31 32 63
Copyright - © All rights reserved. Zend Technologies, Inc.18
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»
Copyright - © All rights reserved. Zend Technologies, Inc.19
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
Copyright - © All rights reserved. Zend Technologies, Inc.20
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 (Неизменяемые массивы)
Copyright - © All rights reserved. Zend Technologies, Inc.21
zval (object/PHP 5)
handlers
zend_class_entry *ce
typerefcount is_ref unused
zval *propertyN
HashTable *guards
0 7 8 31 32 63
handle
...
...
...
HashTable *properies
zval *property1
...
zval
zval
HEAP
OBJECT STORE
Copyright - © All rights reserved. Zend Technologies, Inc.22
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
Copyright - © All rights reserved. Zend Technologies, Inc.23
zval (reference)
flags
value
type reserved
typerefcount flags gc_info
zval val
0 7 8 31 32 63
Copyright - © All rights reserved. Zend Technologies, Inc.24
zval (IS_BOOL -> IS_FALSE + IS_TRUE)
ZEND_VM_HANDLER(43, ZEND_JMPZ,
CONST|TMP|VAR|CV, ANY)
{
long ret;
zval *val =
GET_OP1_ZVAL_PTR(BP_VAR_R);
if (Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
} else {
ret = i_zend_is_true(val TSRMLS_CC);
FREE_OP1();
CHECK_EXCEPTION();
}
if (!ret) {
ZEND_VM_SET_OPCODE(
opline->op2.jmp_addr);
ZEND_VM_CONTINUE();
}
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(43, ZEND_JMPZ,
CONST|TMP|VAR|CV, ANY)
{
zval *val =
GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (Z_TYPE_P(val) == IS_TRUE) {
ZEND_VM_SET_OPCODE(opline + 1);
ZEND_VM_CONTINUE();
} else if (Z_TYPE_P(val) <= IS_TRUE) {
ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
ZEND_VM_CONTINUE();
}
if (i_zend_is_true(val TSRMLS_CC)) {
opline++;
} else {
opline = opline->op2.jmp_addr;
}
FREE_OP1();
ZEND_VM_JMP(opline);
}
type check
value read
value check
type check
slow path
slow path
Copyright - © All rights reserved. Zend Technologies, Inc.25
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
...
...
...
Copyright - © All rights reserved. Zend Technologies, Inc.26
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
...
... int(3), rc=1
HEAP
Arg1:
Arg2:
Copyright - © All rights reserved. Zend Technologies, Inc.27
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
... int(3), rc=1
int(5), rc=1
HEAP
Arg1:
Arg2:
Copyright - © All rights reserved. Zend Technologies, Inc.28
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
...
...
...
... int(3), rc=1
int(5), rc=1
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.29
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
...
...
... int(3), rc=2
int(5), rc=1
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.30
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
...
... int(3), rc=2
int(5), rc=2
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.31
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
int(8)
... int(3), rc=2
int(5), rc=2
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.32
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
CALL FRAME
int(8)
... int(3), rc=2
int(5), rc=2
HEAP
Arg1:
Arg2:
$a:
$b:
Copyright - © All rights reserved. Zend Technologies, Inc.33
VM Calling Convention (PHP 5.*)
RECV 1, $a
RECV 2, $b
ADD $a,$b,TMP1
RETURN TMP1
foo:
_main:
SEND_VAL 3
SEND_VAL 5
DO_FCALL “foo”/2
RETURN null
function foo($a, $b) {
return $a + $b;
}
foo(3, 5);
VM STACK (pointers to zvals)
...
...
...
Copyright - © All rights reserved. Zend Technologies, Inc.34
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
new instruction embedded zvals
instead of pointers
Copyright - © All rights reserved. Zend Technologies, Inc.35
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
Copyright - © All rights reserved. Zend Technologies, Inc.36
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
Copyright - © All rights reserved. Zend Technologies, Inc.37
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)
Copyright - © All rights reserved. Zend Technologies, Inc.38
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
Copyright - © All rights reserved. Zend Technologies, Inc.39
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:
Copyright - © All rights reserved. Zend Technologies, Inc.40
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:
Copyright - © All rights reserved. Zend Technologies, Inc.41
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
NOTE:
● func_get_arg*() changed behavior
● function foo($_, $_) {} is not allowed
Copyright - © All rights reserved. Zend Technologies, Inc.42
Новый менеджер памяти
●
В PHP 5 менеджмент памяти потребляет более 20% процессорного времени
(на Wordpress)
●
Новый ММ отказался от алгоритмов dlmalloc и перешел на что-то,
напоминающее jemalloc
●
Уменьшены издержки памяти на служебную информацию
●
Использование поиска по битовым маскам вместо обхода списков и деревьев
●
Лучшее использование кэшей CPU
●
Специализация под часто используемые размеры блоков
●
Полностью прозрачная реализация
●
Накладные расходы ММ уменьшены до 5%
Copyright - © All rights reserved. Zend Technologies, Inc.43
Множество мелких усовершенствований
●
Быстрое API для разбора параметров внутренних функций
●
Новые инструкции VM (конкатенация строк, специализация, супер-инструкции)
●
Некоторые внутренние функции превращены в инструкции VM (strlen, is_int)
●
Использование регистров CPU под регистры VM (IP и FP)
●
Новый API для итерации по HashTable
●
Оптимизация функций дублирования и удаления массивов
●
Использование счетчиков ссылок вместо копирования везде, где можно
●
PCRE JIT
●
Оптимизация внутренних функций
●
Оптимизация serialize()
●
Уменьшение размера кода и обрабатываемых данных
Copyright - © All rights reserved. Zend Technologies, Inc.44
Откуда ускорение? (WordPress/PHP 7.0)
Copyright - © All rights reserved. Zend Technologies, Inc.45
PHP 5.6 PHP 7.0 улучшение
VM 27% 19,494M 46% 9,005M 2 раза
alloc 22% 15,575M 5% 905M 17 раз
hash 13% 9,590M 13% 2.450M 4 раза
libc 6% 4.585M 8% 1,598M 3 раза
Total: 100% 70,798M 100% 19,462M 3.5 раз
Откуда ускорение? (WordPress)
Copyright - © All rights reserved. Zend Technologies, Inc.46
Производительность PHP 7
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov
0
5
10
15
20
25
30
24.04 24.04 24.04
22.64
18.62
16.37
15.28 14.86
14.16 13.83 13.56 13.28
12.58 12.39
11.67 11.48 11.08 11.04 10.88 10.69 10.5 10.4 10.4
sec
●
Время исполнения 1000 запросов к Wordpress-3.6.0
●
php-cgi -T 1000 /.../wordpress/index.php > /dev/null
Copyright - © All rights reserved. Zend Technologies, Inc.47
PHP 5 против PHP 7 против HHVM
ZF1 Hello
ZF2 Test
Magento (home)
SugarCRM (login)
Laravel
Drupal 7
Drupal 8
Mediawiki
Wordpress-4.1
0
0.5
1
1.5
2
2.5
3
PHP 5.6
PHP 7.0.0
HHVM 3.10.0
Copyright - © All rights reserved. Zend Technologies, Inc.48
PHP 5 против PHP 7 против HHVM (версия Facebook)
Copyright - © All rights reserved. Zend Technologies, Inc.49
Badoo перешли на PHP 7.0 и сэкономили $1M
Copyright - © All rights reserved. Zend Technologies, Inc.50
Что дальше?
●
PHP 7.0
●
Оптимизация структур данных
●
PHP 7.1
●
Анализатор потоков данных
●
Вывод типов
●
Глобальный оптимизатор для байт-кода PHP
●
Оптимизация и cпециализация интерпретатора
Copyright - © All rights reserved. Zend Technologies, Inc.51
PHP 7.1
●
Уже вышел RC3 (29-го сентября 2016)
●
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()
Copyright - © All rights reserved. Zend Technologies, Inc.52
PHP 7.1 Optimizer (script)
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.53
PHP 7.1 Optimizer (bytecode)
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
RETURN $sum
RETURN null
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.54
PHP 7.1 Optimizer (trivial optimization)
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
RETURN $sum
RETURN null
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.55
PHP 7.1 Optimizer (trivial optimization)
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
RETURN $sum
RETURN null
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.56
PHP 7.1 Optimizer (trivial optimization)
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
RETURN $sum
RETURN null
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.57
PHP 7.1 Optimizer (trivial optimization)
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
RETURN $sum
RETURN null
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.58
PHP 7.1 Optimizer (trivial optimization)
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
RETURN $sum
RETURN null
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.59
PHP 7.1 Optimizer (trivial optimization)
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
RETURN $sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.60
PHP 7.1 Optimizer (Control Flow Graph)
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
RETURN $sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.61
PHP 7.1 Optimizer (Control Flow Graph)
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
RETURN $sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.62
PHP 7.1 Optimizer (Control Flow Graph)
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
RETURN $sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.63
PHP 7.1 Optimizer (Control Flow Graph)
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
RETURN $sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.64
PHP 7.1 Optimizer (Static Single Assignmnt Form)
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
RETURN $?.sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.65
PHP 7.1 Optimizer (Static Single Assignmnt Form)
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
RETURN $?.sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.66
PHP 7.1 Optimizer (Static Single Assignmnt Form)
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
RETURN $5.sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.67
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
RETURN $5.sum
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
Copyright - © All rights reserved. Zend Technologies, Inc.68
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
RETURN $5.sum
Copyright - © All rights reserved. Zend Technologies, Inc.69
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
RETURN $5.sum
Copyright - © All rights reserved. Zend Technologies, Inc.70
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
RETURN $5.sum
Copyright - © All rights reserved. Zend Technologies, Inc.71
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
RETURN $5.sum
Copyright - © All rights reserved. Zend Technologies, Inc.72
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
RETURN $5.sum [long]
Copyright - © All rights reserved. Zend Technologies, Inc.73
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
RETURN $5.sum [long]
Copyright - © All rights reserved. Zend Technologies, Inc.74
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.75
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
RETURN $5.sum
Copyright - © All rights reserved. Zend Technologies, Inc.76
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..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
RETURN $5.sum [0..++]
Copyright - © All rights reserved. Zend Technologies, Inc.77
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.78
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.79
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.80
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.81
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.82
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.83
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.84
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
RETURN $5.sum [long, double]
Copyright - © All rights reserved. Zend Technologies, Inc.85
PHP 7.1 Optimizer (final result)
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
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
RETURN $sum
RETURN null
Copyright - © All rights reserved. Zend Technologies, Inc.86
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
Copyright - © All rights reserved. Zend Technologies, Inc.87
Что дальше?
●
JIT (для PHP 7.2 или PHP 8)
●
Проект стартовал в августе 2016 и находится в самом начале пути
●
Для генерации машинного кода используется DynAsm из LuaJIT-2
●
https://github.com/zendtech/php-src/tree/jit-dynasm/ext/opcache/jit
●
Уже сегодня ускорение на bench.php в 3 раза (в 75 раз быстрее PHP 5.0)
●
На реальных приложениях ускорения нет
●
Предыдущая попытка, основанная на LLVM, давала на bench.php 2.5
кратное ускорение
●
На реальных приложениях была не применима (очень долго
компилировала)
●
https://github.com/zendtech/php-src/tree/zend-jit/ext/opcache/jit
Copyright - © All rights reserved. Zend Technologies, Inc.88
PHP ? - JIT
JIT$sum:
sub $0xc, %esp
mov $0x0, 0x30(%esi)
mov $0x4, 0x38(%esi)
mov $0x0, 0x40(%esi)
mov $0x4, 0x48(%esi)
jmp .L3
.L1:
cmp $0x4, 0x38(%esi)
jnz .L6
mov 0x30(%esi), %eax
add 0x40(%esi), %eax
jo .L5
mov %eax, 0x30(%esi)
.L2:
inc 0x40(%esi)
.L3
mov $0xeca7fa64, %edi
cmp $0x0, EG(vm_interrupt)
jnz JIT$$interrupt_handler
mov 0x40(%esi), %eax
cmp $0x64, %eax
jl .L1
...
$i++
$i < 100
$sum = 0
$i =0
<?php
function sum() {
$sum = 0;
for ($i = 0; $i < 100; $i++) {
$sum = $sum + $i;
}
return $sum;
}
$sum = $sum + $i
Copyright - © All rights reserved. Zend Technologies, Inc.89
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.15.2 (--count=2)
PHP/dynasm-jit
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.025
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.
Старый JIT (быстрее некуда :)
Новый JIT
Confidential - © All rights reserved. Zend Technologies, Inc.90
Вопросы?
Dmitry Stogov
Principal Engineer at Zend Technologies
@dstogov
dmitry@zend.com
www.zend.com
Copyright - © All rights reserved. Zend Technologies, Inc.91
Хотите еще быстрее? – HUGE TLB или HUGE PAGE
●
CPU использует виртуальную память с 4KB страницам
●
CPU TLB cahce содержит всего 64-512 слотов => 256KB-2M
●
TLB промахи требуют много времени для обработки
●
Решение – страницы размером 2MB
●
PHP-7, если может, использует 2M страницы для менеджера памяти и разделяемой
памяти opcahce, где хранятся скомпилированные скрипты
●
opcache.huge_tlb_caches=1 так же копирует сегмент кода в Huge Pages
●
grep "Huge" /proc/meminfo
AnonHugePages: 0 kB
HugePages_Total: 512
HugePages_Free: 497
HugePages_Rsvd: 55
HugePages_Surp: 0
Hugepagesize: 2048 kB
●
https://wiki.debian.org/Hugepages#Enabling_HugeTlbPage
Copyright - © All rights reserved. Zend Technologies, Inc.92
Хотите еще быстрее? – 32-битная сборка?
●
Почти все современные процессоры 64-битные
●
Почти все современные ОС 64-битные
●
X86_64 может обрабатывать данные, используя меньшее количество
инструкций
●
X86_64 предлагает 8 дополнительных регистров общего назначения
●
Но: 64-битные адреса занимают больше места, требуют больше памяти, что
ведет к увеличению промахов в CPU кэше и уменьшению производительности.
●
Использование 32-битного PHP (gcc -m32 -sse2) обычно дает 5% прирост
Copyright - © All rights reserved. Zend Technologies, Inc.93
Хотите еще быстрее? – PGO/FDO сборка
●
make prof-gen
●
sapi/cgi/php-cgi -T 3000 /.../wordpress/index.php > /dev/null
●
make prof-clean
●
make prof-use
●
Скорость +8%
●
Объем кода -8% (size sapi/cli/php)
Copyright - © All rights reserved. Zend Technologies, Inc.94
Хотите еще быстрее? – opcache.file_cahe
●
PHP7 opcache дает возможность дополнительно кэшировать скрипты на диске
(запрещено по умолчанию)
●
mkdir /tmp/opcahe
●
Добавить opcache.file_cahce=/tmp/opcache в php.ini
●
Уменьшает пиковые нагрузки при рестарте PHP и переполнении SHM кэша
●
Улучшает время отклика в эти моменты в 2-3 раза
●
Может использоваться в сценариях апгрейда (можно предварительно
загрузить дисковый кэш)
●
file_cache может работать вообще без SHM
Copyright - © All rights reserved. Zend Technologies, Inc.95
Не забывайте про оптимизацию всего стека
●
Оптимизация вашего PHP приложения даст наибольший результат
●
Кэшируйте все, что можно
●
Правильно выбирайте количество PHP процессов (больше – не значит лучше)
●
MariaDB, сконфигурированная по умолчанию, замедляла Wordpress почти на
30%
query_cache_size=16M
query_cache_type=1
●
TCP stack
●
Не отключайте Hyper-Threading

More Related Content

What's hot

Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterSimen Li
 
Distributed systems at ok.ru #rigadevday
Distributed systems at ok.ru #rigadevdayDistributed systems at ok.ru #rigadevday
Distributed systems at ok.ru #rigadevdayodnoklassniki.ru
 
My talk at Linux Piter 2015
My talk at Linux Piter 2015My talk at Linux Piter 2015
My talk at Linux Piter 2015Alex Chistyakov
 
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013odnoklassniki.ru
 
HandlerSocket - A NoSQL plugin for MySQL
HandlerSocket - A NoSQL plugin for MySQLHandlerSocket - A NoSQL plugin for MySQL
HandlerSocket - A NoSQL plugin for MySQLJui-Nan Lin
 
REDIS intro and how to use redis
REDIS intro and how to use redisREDIS intro and how to use redis
REDIS intro and how to use redisKris Jeong
 
Java Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVMJava Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVModnoklassniki.ru
 
スローダウン、ハングを一発解決 スレッドダンプはトラブルシューティングの味方 #wlstudy
スローダウン、ハングを一発解決 スレッドダンプはトラブルシューティングの味方 #wlstudyスローダウン、ハングを一発解決 スレッドダンプはトラブルシューティングの味方 #wlstudy
スローダウン、ハングを一発解決 スレッドダンプはトラブルシューティングの味方 #wlstudyYusuke Yamamoto
 
Everything you wanted to know about Stack Traces and Heap Dumps
Everything you wanted to know about Stack Traces and Heap DumpsEverything you wanted to know about Stack Traces and Heap Dumps
Everything you wanted to know about Stack Traces and Heap DumpsAndrei Pangin
 
Indexierung mit MySQL
Indexierung mit MySQLIndexierung mit MySQL
Indexierung mit MySQLFromDual GmbH
 
2015.07.16 Способы диагностики PostgreSQL
2015.07.16 Способы диагностики PostgreSQL2015.07.16 Способы диагностики PostgreSQL
2015.07.16 Способы диагностики PostgreSQLdev1ant
 
How to cook lettuce @Java casual
How to cook lettuce @Java casualHow to cook lettuce @Java casual
How to cook lettuce @Java casualGo Hagiwara
 
Mасштабирование микросервисов на Go, Matt Heath (Hailo)
Mасштабирование микросервисов на Go, Matt Heath (Hailo)Mасштабирование микросервисов на Go, Matt Heath (Hailo)
Mасштабирование микросервисов на Go, Matt Heath (Hailo)Ontico
 
MySQL Replication Troubleshooting for Oracle DBAs
MySQL Replication Troubleshooting for Oracle DBAsMySQL Replication Troubleshooting for Oracle DBAs
MySQL Replication Troubleshooting for Oracle DBAsSveta Smirnova
 
DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술
DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술
DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술John Kim
 
Доклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang MeetupДоклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang MeetupBadoo Development
 
Multithreading in Node.js and JavaScript
Multithreading in Node.js and JavaScriptMultithreading in Node.js and JavaScript
Multithreading in Node.js and JavaScriptTimur Shemsedinov
 
Large Scale Log collection using LogStash & mongoDB
Large Scale Log collection using LogStash & mongoDB Large Scale Log collection using LogStash & mongoDB
Large Scale Log collection using LogStash & mongoDB Gaurav Bhardwaj
 
Kettunen, miaubiz fuzzing at scale and in style
Kettunen, miaubiz   fuzzing at scale and in styleKettunen, miaubiz   fuzzing at scale and in style
Kettunen, miaubiz fuzzing at scale and in styleDefconRussia
 

What's hot (20)

Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitter
 
Distributed systems at ok.ru #rigadevday
Distributed systems at ok.ru #rigadevdayDistributed systems at ok.ru #rigadevday
Distributed systems at ok.ru #rigadevday
 
My talk at Linux Piter 2015
My talk at Linux Piter 2015My talk at Linux Piter 2015
My talk at Linux Piter 2015
 
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
Being closer to Cassandra by Oleg Anastasyev. Talk at Cassandra Summit EU 2013
 
HandlerSocket - A NoSQL plugin for MySQL
HandlerSocket - A NoSQL plugin for MySQLHandlerSocket - A NoSQL plugin for MySQL
HandlerSocket - A NoSQL plugin for MySQL
 
REDIS intro and how to use redis
REDIS intro and how to use redisREDIS intro and how to use redis
REDIS intro and how to use redis
 
Java Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVMJava Runtime: повседневные обязанности JVM
Java Runtime: повседневные обязанности JVM
 
スローダウン、ハングを一発解決 スレッドダンプはトラブルシューティングの味方 #wlstudy
スローダウン、ハングを一発解決 スレッドダンプはトラブルシューティングの味方 #wlstudyスローダウン、ハングを一発解決 スレッドダンプはトラブルシューティングの味方 #wlstudy
スローダウン、ハングを一発解決 スレッドダンプはトラブルシューティングの味方 #wlstudy
 
Everything you wanted to know about Stack Traces and Heap Dumps
Everything you wanted to know about Stack Traces and Heap DumpsEverything you wanted to know about Stack Traces and Heap Dumps
Everything you wanted to know about Stack Traces and Heap Dumps
 
Indexierung mit MySQL
Indexierung mit MySQLIndexierung mit MySQL
Indexierung mit MySQL
 
Event loop
Event loopEvent loop
Event loop
 
2015.07.16 Способы диагностики PostgreSQL
2015.07.16 Способы диагностики PostgreSQL2015.07.16 Способы диагностики PostgreSQL
2015.07.16 Способы диагностики PostgreSQL
 
How to cook lettuce @Java casual
How to cook lettuce @Java casualHow to cook lettuce @Java casual
How to cook lettuce @Java casual
 
Mасштабирование микросервисов на Go, Matt Heath (Hailo)
Mасштабирование микросервисов на Go, Matt Heath (Hailo)Mасштабирование микросервисов на Go, Matt Heath (Hailo)
Mасштабирование микросервисов на Go, Matt Heath (Hailo)
 
MySQL Replication Troubleshooting for Oracle DBAs
MySQL Replication Troubleshooting for Oracle DBAsMySQL Replication Troubleshooting for Oracle DBAs
MySQL Replication Troubleshooting for Oracle DBAs
 
DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술
DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술
DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술
 
Доклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang MeetupДоклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang Meetup
 
Multithreading in Node.js and JavaScript
Multithreading in Node.js and JavaScriptMultithreading in Node.js and JavaScript
Multithreading in Node.js and JavaScript
 
Large Scale Log collection using LogStash & mongoDB
Large Scale Log collection using LogStash & mongoDB Large Scale Log collection using LogStash & mongoDB
Large Scale Log collection using LogStash & mongoDB
 
Kettunen, miaubiz fuzzing at scale and in style
Kettunen, miaubiz   fuzzing at scale and in styleKettunen, miaubiz   fuzzing at scale and in style
Kettunen, miaubiz fuzzing at scale and in style
 

Similar to Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technologies)

DevOps in PHP environment
DevOps in PHP environmentDevOps in PHP environment
DevOps in PHP environmentEvaldo Felipe
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6Wim Godden
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7julien pauli
 
Php7 HHVM and co
Php7 HHVM and coPhp7 HHVM and co
Php7 HHVM and coweltling
 
CodePolitan Webinar: The Rise of PHP
CodePolitan Webinar: The Rise of PHPCodePolitan Webinar: The Rise of PHP
CodePolitan Webinar: The Rise of PHPSteeven Salim
 
A quick start on Zend Framework 2
A quick start on Zend Framework 2A quick start on Zend Framework 2
A quick start on Zend Framework 2Enrico Zimuel
 
(phpconftw2012) PHP as a Middleware in Embedded Systems
(phpconftw2012) PHP as a Middleware in Embedded Systems(phpconftw2012) PHP as a Middleware in Embedded Systems
(phpconftw2012) PHP as a Middleware in Embedded Systemssosorry
 
PHP in 2018 - Q1 - AFUP Limoges
PHP in 2018 - Q1 - AFUP LimogesPHP in 2018 - Q1 - AFUP Limoges
PHP in 2018 - Q1 - AFUP Limoges✅ William Pinaud
 
PHP7 - The New Engine for old good train
PHP7 - The New Engine for old good trainPHP7 - The New Engine for old good train
PHP7 - The New Engine for old good trainXinchen Hui
 
Php7 hhvm and co
Php7 hhvm and coPhp7 hhvm and co
Php7 hhvm and coPierre Joye
 
PHP QA Tools
PHP QA ToolsPHP QA Tools
PHP QA Toolsrjsmelo
 
What To Expect From PHP7
What To Expect From PHP7What To Expect From PHP7
What To Expect From PHP7Codemotion
 
Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Wim Godden
 
node.js - Eventful JavaScript on the Server
node.js - Eventful JavaScript on the Servernode.js - Eventful JavaScript on the Server
node.js - Eventful JavaScript on the ServerDavid Ruiz
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4Wim Godden
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7Wim Godden
 
Symfony live 2017_php7_performances
Symfony live 2017_php7_performancesSymfony live 2017_php7_performances
Symfony live 2017_php7_performancesjulien pauli
 

Similar to Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technologies) (20)

Cryptography in PHP: Some Use Cases
Cryptography in PHP: Some Use CasesCryptography in PHP: Some Use Cases
Cryptography in PHP: Some Use Cases
 
DevOps in PHP environment
DevOps in PHP environmentDevOps in PHP environment
DevOps in PHP environment
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7
 
Php7 HHVM and co
Php7 HHVM and coPhp7 HHVM and co
Php7 HHVM and co
 
CodePolitan Webinar: The Rise of PHP
CodePolitan Webinar: The Rise of PHPCodePolitan Webinar: The Rise of PHP
CodePolitan Webinar: The Rise of PHP
 
A quick start on Zend Framework 2
A quick start on Zend Framework 2A quick start on Zend Framework 2
A quick start on Zend Framework 2
 
(phpconftw2012) PHP as a Middleware in Embedded Systems
(phpconftw2012) PHP as a Middleware in Embedded Systems(phpconftw2012) PHP as a Middleware in Embedded Systems
(phpconftw2012) PHP as a Middleware in Embedded Systems
 
PHP in 2018 - Q1 - AFUP Limoges
PHP in 2018 - Q1 - AFUP LimogesPHP in 2018 - Q1 - AFUP Limoges
PHP in 2018 - Q1 - AFUP Limoges
 
PHP7 - The New Engine for old good train
PHP7 - The New Engine for old good trainPHP7 - The New Engine for old good train
PHP7 - The New Engine for old good train
 
ZF2 Presentation @PHP Tour 2011 in Lille
ZF2 Presentation @PHP Tour 2011 in LilleZF2 Presentation @PHP Tour 2011 in Lille
ZF2 Presentation @PHP Tour 2011 in Lille
 
Php7 hhvm and co
Php7 hhvm and coPhp7 hhvm and co
Php7 hhvm and co
 
PHP QA Tools
PHP QA ToolsPHP QA Tools
PHP QA Tools
 
What To Expect From PHP7
What To Expect From PHP7What To Expect From PHP7
What To Expect From PHP7
 
Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?
 
node.js - Eventful JavaScript on the Server
node.js - Eventful JavaScript on the Servernode.js - Eventful JavaScript on the Server
node.js - Eventful JavaScript on the Server
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7
 
Symfony live 2017_php7_performances
Symfony live 2017_php7_performancesSymfony live 2017_php7_performances
Symfony live 2017_php7_performances
 
NodeJS for Beginner
NodeJS for BeginnerNodeJS for Beginner
NodeJS for Beginner
 

More from Ontico

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...Ontico
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Ontico
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Ontico
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Ontico
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Ontico
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Ontico
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Ontico
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)Ontico
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)Ontico
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Ontico
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Ontico
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Ontico
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Ontico
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)Ontico
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Ontico
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Ontico
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...Ontico
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Ontico
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Ontico
 
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)Ontico
 

More from Ontico (20)

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
 
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
Как мы учились чинить самолеты в воздухе / Евгений Коломеец (Virtuozzo)
 

Recently uploaded

List of Accredited Concrete Batching Plant.pdf
List of Accredited Concrete Batching Plant.pdfList of Accredited Concrete Batching Plant.pdf
List of Accredited Concrete Batching Plant.pdfisabel213075
 
Virtual memory management in Operating System
Virtual memory management in Operating SystemVirtual memory management in Operating System
Virtual memory management in Operating SystemRashmi Bhat
 
Input Output Management in Operating System
Input Output Management in Operating SystemInput Output Management in Operating System
Input Output Management in Operating SystemRashmi Bhat
 
Forming section troubleshooting checklist for improving wire life (1).ppt
Forming section troubleshooting checklist for improving wire life (1).pptForming section troubleshooting checklist for improving wire life (1).ppt
Forming section troubleshooting checklist for improving wire life (1).pptNoman khan
 
TEST CASE GENERATION GENERATION BLOCK BOX APPROACH
TEST CASE GENERATION GENERATION BLOCK BOX APPROACHTEST CASE GENERATION GENERATION BLOCK BOX APPROACH
TEST CASE GENERATION GENERATION BLOCK BOX APPROACHSneha Padhiar
 
Module-1-(Building Acoustics) Noise Control (Unit-3). pdf
Module-1-(Building Acoustics) Noise Control (Unit-3). pdfModule-1-(Building Acoustics) Noise Control (Unit-3). pdf
Module-1-(Building Acoustics) Noise Control (Unit-3). pdfManish Kumar
 
SOFTWARE ESTIMATION COCOMO AND FP CALCULATION
SOFTWARE ESTIMATION COCOMO AND FP CALCULATIONSOFTWARE ESTIMATION COCOMO AND FP CALCULATION
SOFTWARE ESTIMATION COCOMO AND FP CALCULATIONSneha Padhiar
 
Energy Awareness training ppt for manufacturing process.pptx
Energy Awareness training ppt for manufacturing process.pptxEnergy Awareness training ppt for manufacturing process.pptx
Energy Awareness training ppt for manufacturing process.pptxsiddharthjain2303
 
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.pptROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.pptJohnWilliam111370
 
A brief look at visionOS - How to develop app on Apple's Vision Pro
A brief look at visionOS - How to develop app on Apple's Vision ProA brief look at visionOS - How to develop app on Apple's Vision Pro
A brief look at visionOS - How to develop app on Apple's Vision ProRay Yuan Liu
 
CS 3251 Programming in c all unit notes pdf
CS 3251 Programming in c all unit notes pdfCS 3251 Programming in c all unit notes pdf
CS 3251 Programming in c all unit notes pdfBalamuruganV28
 
Novel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsNovel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsResearcher Researcher
 
Theory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfTheory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfShreyas Pandit
 
multiple access in wireless communication
multiple access in wireless communicationmultiple access in wireless communication
multiple access in wireless communicationpanditadesh123
 
KCD Costa Rica 2024 - Nephio para parvulitos
KCD Costa Rica 2024 - Nephio para parvulitosKCD Costa Rica 2024 - Nephio para parvulitos
KCD Costa Rica 2024 - Nephio para parvulitosVictor Morales
 
Immutable Image-Based Operating Systems - EW2024.pdf
Immutable Image-Based Operating Systems - EW2024.pdfImmutable Image-Based Operating Systems - EW2024.pdf
Immutable Image-Based Operating Systems - EW2024.pdfDrew Moseley
 
Mine Environment II Lab_MI10448MI__________.pptx
Mine Environment II Lab_MI10448MI__________.pptxMine Environment II Lab_MI10448MI__________.pptx
Mine Environment II Lab_MI10448MI__________.pptxRomil Mishra
 
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONTHE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONjhunlian
 
Secure Key Crypto - Tech Paper JET Tech Labs
Secure Key Crypto - Tech Paper JET Tech LabsSecure Key Crypto - Tech Paper JET Tech Labs
Secure Key Crypto - Tech Paper JET Tech Labsamber724300
 
Javier_Fernandez_CARS_workshop_presentation.pptx
Javier_Fernandez_CARS_workshop_presentation.pptxJavier_Fernandez_CARS_workshop_presentation.pptx
Javier_Fernandez_CARS_workshop_presentation.pptxJavier Fernández Muñoz
 

Recently uploaded (20)

List of Accredited Concrete Batching Plant.pdf
List of Accredited Concrete Batching Plant.pdfList of Accredited Concrete Batching Plant.pdf
List of Accredited Concrete Batching Plant.pdf
 
Virtual memory management in Operating System
Virtual memory management in Operating SystemVirtual memory management in Operating System
Virtual memory management in Operating System
 
Input Output Management in Operating System
Input Output Management in Operating SystemInput Output Management in Operating System
Input Output Management in Operating System
 
Forming section troubleshooting checklist for improving wire life (1).ppt
Forming section troubleshooting checklist for improving wire life (1).pptForming section troubleshooting checklist for improving wire life (1).ppt
Forming section troubleshooting checklist for improving wire life (1).ppt
 
TEST CASE GENERATION GENERATION BLOCK BOX APPROACH
TEST CASE GENERATION GENERATION BLOCK BOX APPROACHTEST CASE GENERATION GENERATION BLOCK BOX APPROACH
TEST CASE GENERATION GENERATION BLOCK BOX APPROACH
 
Module-1-(Building Acoustics) Noise Control (Unit-3). pdf
Module-1-(Building Acoustics) Noise Control (Unit-3). pdfModule-1-(Building Acoustics) Noise Control (Unit-3). pdf
Module-1-(Building Acoustics) Noise Control (Unit-3). pdf
 
SOFTWARE ESTIMATION COCOMO AND FP CALCULATION
SOFTWARE ESTIMATION COCOMO AND FP CALCULATIONSOFTWARE ESTIMATION COCOMO AND FP CALCULATION
SOFTWARE ESTIMATION COCOMO AND FP CALCULATION
 
Energy Awareness training ppt for manufacturing process.pptx
Energy Awareness training ppt for manufacturing process.pptxEnergy Awareness training ppt for manufacturing process.pptx
Energy Awareness training ppt for manufacturing process.pptx
 
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.pptROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
ROBOETHICS-CCS345 ETHICS AND ARTIFICIAL INTELLIGENCE.ppt
 
A brief look at visionOS - How to develop app on Apple's Vision Pro
A brief look at visionOS - How to develop app on Apple's Vision ProA brief look at visionOS - How to develop app on Apple's Vision Pro
A brief look at visionOS - How to develop app on Apple's Vision Pro
 
CS 3251 Programming in c all unit notes pdf
CS 3251 Programming in c all unit notes pdfCS 3251 Programming in c all unit notes pdf
CS 3251 Programming in c all unit notes pdf
 
Novel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending ActuatorsNovel 3D-Printed Soft Linear and Bending Actuators
Novel 3D-Printed Soft Linear and Bending Actuators
 
Theory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdfTheory of Machine Notes / Lecture Material .pdf
Theory of Machine Notes / Lecture Material .pdf
 
multiple access in wireless communication
multiple access in wireless communicationmultiple access in wireless communication
multiple access in wireless communication
 
KCD Costa Rica 2024 - Nephio para parvulitos
KCD Costa Rica 2024 - Nephio para parvulitosKCD Costa Rica 2024 - Nephio para parvulitos
KCD Costa Rica 2024 - Nephio para parvulitos
 
Immutable Image-Based Operating Systems - EW2024.pdf
Immutable Image-Based Operating Systems - EW2024.pdfImmutable Image-Based Operating Systems - EW2024.pdf
Immutable Image-Based Operating Systems - EW2024.pdf
 
Mine Environment II Lab_MI10448MI__________.pptx
Mine Environment II Lab_MI10448MI__________.pptxMine Environment II Lab_MI10448MI__________.pptx
Mine Environment II Lab_MI10448MI__________.pptx
 
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTIONTHE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
THE SENDAI FRAMEWORK FOR DISASTER RISK REDUCTION
 
Secure Key Crypto - Tech Paper JET Tech Labs
Secure Key Crypto - Tech Paper JET Tech LabsSecure Key Crypto - Tech Paper JET Tech Labs
Secure Key Crypto - Tech Paper JET Tech Labs
 
Javier_Fernandez_CARS_workshop_presentation.pptx
Javier_Fernandez_CARS_workshop_presentation.pptxJavier_Fernandez_CARS_workshop_presentation.pptx
Javier_Fernandez_CARS_workshop_presentation.pptx
 

Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technologies)

  • 1. Confidential - © All rights reserved. Zend Technologies, Inc.1 Copyright - © All rights reserved. Zend Technologies, Inc. Как мы сделали PHP 7 в два раза быстрее. Дмитрий Стогов HighLoad++ 2016, Москва Principal Engineer at Zend Technologies
  • 2. Copyright - © All rights reserved. Zend Technologies, Inc.2 Кто Я? ● Познакомился с программированием в 1984 ● Работаю в ИТ с 1991 ● Первое знакомство с PHP в 2002 ● Автор Turck MMCache для PHP (eAccelerator) ● Работаю в Zend Technologies с 2004 ● Сейчас ведущий инженер ● Автор ext/soap и pecl/perl ● Один из ведущих разработчиков Open Source PHP ● Майнтейнер Zend OPcache ● Лидер проекта PHPNG, легшего в основу PHP 7 ● Лидер разработки JIT для PHP
  • 3. Copyright - © All rights reserved. Zend Technologies, Inc.3 PHP – Personal Home Page ● Инструмент для создания персональных веб-страниц ● Первый релиз PHP/FI 2.0 от Rasmus Lerdorf 8 июня 1995 ● В 1998 Andi Gutmans и Zeev Suraski выпустили PHP 3 ● PHP 4, основанный на Zend Engine, вышел в 2000 ● PHP 5 с переработанной ООП моделью вышел в 2004 ● ZendFramework в 2007 ● Сегодня более 70% сайтов интернета используют PHP ● C 2010 Facebook работает над альтернативной реализацией – HHVM ● В декабре 2015 вышел PHP 7 ● В ноябре 2016 должен выйти PHP 7.1
  • 4. Copyright - © All rights reserved. Zend Technologies, Inc.4 Производительность PHP на синтетических тестах 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 - Dec 2015 7.1 - Oct 2016 HHVM-3.15.2 12.68 12.54 4.68 4.20 2.91 2.18 2.03 1.92 0.78 0.50 0.38 bench.php [sec] (чем меньше, тем лучше) sec PHP-7.1 еще на треть быстрее PHP-7.0, но все еще медленнее HHVM (на тестах!)
  • 5. Copyright - © All rights reserved. Zend Technologies, Inc.5 Производительность PHP на реальных приложениях 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 - Dec 2015 7.1 - Oct 2016 HHVM-3.15.2 62 58 64 77 86 105 108 114 298 321 313 WordPress-3.6 Home Page [req/sec] (чем больше, тем лучше) sec
  • 6. Copyright - © All rights reserved. Zend Technologies, Inc.6 Блуждание в трех соснах (около JIT) ● Почти два года потрачено на прототип JIT для PHP-5.5 ● Ускорение для bench.php в 10 раз ● Ускорения для Wordpress нет (при компиляции в несколько минут) Выводы: ● Хороший код возможен при правильном предсказании типов ● Предсказание типов в реальных приложениях работает плохо ● Использование совместимых с PHP структур данных делает генерируемый код неэффективным
  • 7. Copyright - © All rights reserved. Zend Technologies, Inc.7 Что же тормозит? (WordPress/PHP 5.6)
  • 8. Copyright - © All rights reserved. Zend Technologies, Inc.8 PHPNG (New Generation) ● Проект получил свое развитие после попыток создания JIT для PHP ● Рефакторинг (никаких нововведений, 100% совместимость с PHP 5) ● Основная цель — достичь нового уровня производительности и заложить базу для будущих улучшений ● Отделился от основной ветки PHP в январе 2014 ● Две недели ушло на то, чтобы просто скомпилировать ядро ● Еще через две недели заработал bench.php ● Полтора месяца для обеспечения совместимости с Wordpress ● Еще через месяц (к 9 Мая) мы открыли проект ● В августе 2014 принят как основа для будущего PHP 7
  • 9. Copyright - © All rights reserved. Zend Technologies, Inc.9 PHP 7.0 ● Было решено выпускать PHP 7 после PHP 5, пропустив PHP 6 ● GA релиз состоялся в декабре 2015 ● Сейчас доступен PHP-7.0.7 ● Возможность определять скалярные типы аргументов функций и возвращаемых значений ● Исключения вместо фатальных ошибок ● Анонимные классы ● Zero-cost assert() ● Новые операторы и функции (<=>, ??) ● Чистка неконсистентностей
  • 10. Copyright - © All rights reserved. Zend Technologies, Inc.10 zval (PHP 5) typedef struct _zval_struct { union { long lval; double dval; struct { char *val; Int len; } str; HashTable *ht; struct { zend_object_handle handle; zend_object_handlers *handlers; } obj; } value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval; sizeof(zval) == 24 $a = 1; $b = $a; $c = «hello»; $d = $c; $b $c $a $d VM STACK (pointers to zvals) HEAP string( ), rc=2 int(1), rc=2 «hello» ● read type - 2 CPU instructions ● read int value - 2 CPU instructions ● read string value - 3 CPU instructions
  • 11. Copyright - © All rights reserved. Zend Technologies, Inc.11 zval (PHP 5 PHP 7)→ typedef struct _zval_struct { union { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; struct { zend_object_handle handle; zend_object_handlers *handlers; } obj; } value; zend_uint refcount; zend_uchar type; zend_uchar is_ref; } zval; sizeof(zval) == 24 typedef struct _zval_struct { union { zend_long lval; double dval; zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zval *zv; void *ptr; } value; union { struct { zend_uchar type; zend_uchar type_flags; } v; zend_uint type_info; }; uint32_t reserved; } zval; sizeof(zval) == 16 new
  • 12. Copyright - © All rights reserved. Zend Technologies, Inc.12 zval (PHP 5 PHP 7)→ ● read type - 1 CPU instruction ● read int value - 1 CPU instruction ● read string value - 2 CPU instructions $b $c $a $d int(1) string( ) int(1) string( ) VM STACK (zvals) HEAP string, rc=2 «hello» $a = 1; $b = $a; $c = «hello»; $d = $c; $b $c $a $d VM STACK (pointers to zvals) HEAP string( ), rc=2 int(1), rc=2 «hello» ● read type - 2 CPU instructions ● read int value - 2 CPU instructions ● read string value - 3 CPU instructions
  • 13. Copyright - © All rights reserved. Zend Technologies, Inc.13 zval (PHP 5 PHP 7) Copy On Write→ ● no CoW for scalars – few instructions $b $c $a $d int(2) string( ) int(1) string( ) VM STACK (zvals) HEAP string, rc=2 «hello» $a = 1; $b = $a; $c = «hello»; $d = $c; $b = 2; $b $c $a $d VM STACK (pointers to zvals) HEAP string( ), rc=2 int(1), rc=1 «hello» ● CoW - hundreds CPU instructions int(2), rc=1
  • 14. Copyright - © All rights reserved. Zend Technologies, Inc.14 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
  • 15. Copyright - © All rights reserved. Zend Technologies, Inc.15 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
  • 16. Copyright - © All rights reserved. Zend Technologies, Inc.16 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
  • 17. Copyright - © All rights reserved. Zend Technologies, Inc.17 zval (array) flags value type reserved typerefcount flags gc_info HashTable ● IS_ARRAY_IMMUTABLE 0 7 8 31 32 63
  • 18. Copyright - © All rights reserved. Zend Technologies, Inc.18 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»
  • 19. Copyright - © All rights reserved. Zend Technologies, Inc.19 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
  • 20. Copyright - © All rights reserved. Zend Technologies, Inc.20 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 (Неизменяемые массивы)
  • 21. Copyright - © All rights reserved. Zend Technologies, Inc.21 zval (object/PHP 5) handlers zend_class_entry *ce typerefcount is_ref unused zval *propertyN HashTable *guards 0 7 8 31 32 63 handle ... ... ... HashTable *properies zval *property1 ... zval zval HEAP OBJECT STORE
  • 22. Copyright - © All rights reserved. Zend Technologies, Inc.22 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
  • 23. Copyright - © All rights reserved. Zend Technologies, Inc.23 zval (reference) flags value type reserved typerefcount flags gc_info zval val 0 7 8 31 32 63
  • 24. Copyright - © All rights reserved. Zend Technologies, Inc.24 zval (IS_BOOL -> IS_FALSE + IS_TRUE) ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY) { long ret; zval *val = GET_OP1_ZVAL_PTR(BP_VAR_R); if (Z_TYPE_P(val) == IS_BOOL)) { ret = Z_LVAL_P(val); } else { ret = i_zend_is_true(val TSRMLS_CC); FREE_OP1(); CHECK_EXCEPTION(); } if (!ret) { ZEND_VM_SET_OPCODE( opline->op2.jmp_addr); ZEND_VM_CONTINUE(); } ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY) { zval *val = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (Z_TYPE_P(val) == IS_TRUE) { ZEND_VM_SET_OPCODE(opline + 1); ZEND_VM_CONTINUE(); } else if (Z_TYPE_P(val) <= IS_TRUE) { ZEND_VM_SET_OPCODE(opline->op2.jmp_addr); ZEND_VM_CONTINUE(); } if (i_zend_is_true(val TSRMLS_CC)) { opline++; } else { opline = opline->op2.jmp_addr; } FREE_OP1(); ZEND_VM_JMP(opline); } type check value read value check type check slow path slow path
  • 25. Copyright - © All rights reserved. Zend Technologies, Inc.25 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) ... ... ...
  • 26. Copyright - © All rights reserved. Zend Technologies, Inc.26 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) ... ... int(3), rc=1 HEAP Arg1: Arg2:
  • 27. Copyright - © All rights reserved. Zend Technologies, Inc.27 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) ... int(3), rc=1 int(5), rc=1 HEAP Arg1: Arg2:
  • 28. Copyright - © All rights reserved. Zend Technologies, Inc.28 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME ... ... ... ... int(3), rc=1 int(5), rc=1 HEAP Arg1: Arg2: $a: $b:
  • 29. Copyright - © All rights reserved. Zend Technologies, Inc.29 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME ... ... ... int(3), rc=2 int(5), rc=1 HEAP Arg1: Arg2: $a: $b:
  • 30. Copyright - © All rights reserved. Zend Technologies, Inc.30 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME ... ... int(3), rc=2 int(5), rc=2 HEAP Arg1: Arg2: $a: $b:
  • 31. Copyright - © All rights reserved. Zend Technologies, Inc.31 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME int(8) ... int(3), rc=2 int(5), rc=2 HEAP Arg1: Arg2: $a: $b:
  • 32. Copyright - © All rights reserved. Zend Technologies, Inc.32 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) CALL FRAME int(8) ... int(3), rc=2 int(5), rc=2 HEAP Arg1: Arg2: $a: $b:
  • 33. Copyright - © All rights reserved. Zend Technologies, Inc.33 VM Calling Convention (PHP 5.*) RECV 1, $a RECV 2, $b ADD $a,$b,TMP1 RETURN TMP1 foo: _main: SEND_VAL 3 SEND_VAL 5 DO_FCALL “foo”/2 RETURN null function foo($a, $b) { return $a + $b; } foo(3, 5); VM STACK (pointers to zvals) ... ... ...
  • 34. Copyright - © All rights reserved. Zend Technologies, Inc.34 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 new instruction embedded zvals instead of pointers
  • 35. Copyright - © All rights reserved. Zend Technologies, Inc.35 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
  • 36. Copyright - © All rights reserved. Zend Technologies, Inc.36 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
  • 37. Copyright - © All rights reserved. Zend Technologies, Inc.37 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)
  • 38. Copyright - © All rights reserved. Zend Technologies, Inc.38 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
  • 39. Copyright - © All rights reserved. Zend Technologies, Inc.39 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:
  • 40. Copyright - © All rights reserved. Zend Technologies, Inc.40 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:
  • 41. Copyright - © All rights reserved. Zend Technologies, Inc.41 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 NOTE: ● func_get_arg*() changed behavior ● function foo($_, $_) {} is not allowed
  • 42. Copyright - © All rights reserved. Zend Technologies, Inc.42 Новый менеджер памяти ● В PHP 5 менеджмент памяти потребляет более 20% процессорного времени (на Wordpress) ● Новый ММ отказался от алгоритмов dlmalloc и перешел на что-то, напоминающее jemalloc ● Уменьшены издержки памяти на служебную информацию ● Использование поиска по битовым маскам вместо обхода списков и деревьев ● Лучшее использование кэшей CPU ● Специализация под часто используемые размеры блоков ● Полностью прозрачная реализация ● Накладные расходы ММ уменьшены до 5%
  • 43. Copyright - © All rights reserved. Zend Technologies, Inc.43 Множество мелких усовершенствований ● Быстрое API для разбора параметров внутренних функций ● Новые инструкции VM (конкатенация строк, специализация, супер-инструкции) ● Некоторые внутренние функции превращены в инструкции VM (strlen, is_int) ● Использование регистров CPU под регистры VM (IP и FP) ● Новый API для итерации по HashTable ● Оптимизация функций дублирования и удаления массивов ● Использование счетчиков ссылок вместо копирования везде, где можно ● PCRE JIT ● Оптимизация внутренних функций ● Оптимизация serialize() ● Уменьшение размера кода и обрабатываемых данных
  • 44. Copyright - © All rights reserved. Zend Technologies, Inc.44 Откуда ускорение? (WordPress/PHP 7.0)
  • 45. Copyright - © All rights reserved. Zend Technologies, Inc.45 PHP 5.6 PHP 7.0 улучшение VM 27% 19,494M 46% 9,005M 2 раза alloc 22% 15,575M 5% 905M 17 раз hash 13% 9,590M 13% 2.450M 4 раза libc 6% 4.585M 8% 1,598M 3 раза Total: 100% 70,798M 100% 19,462M 3.5 раз Откуда ускорение? (WordPress)
  • 46. Copyright - © All rights reserved. Zend Technologies, Inc.46 Производительность PHP 7 Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov 0 5 10 15 20 25 30 24.04 24.04 24.04 22.64 18.62 16.37 15.28 14.86 14.16 13.83 13.56 13.28 12.58 12.39 11.67 11.48 11.08 11.04 10.88 10.69 10.5 10.4 10.4 sec ● Время исполнения 1000 запросов к Wordpress-3.6.0 ● php-cgi -T 1000 /.../wordpress/index.php > /dev/null
  • 47. Copyright - © All rights reserved. Zend Technologies, Inc.47 PHP 5 против PHP 7 против HHVM ZF1 Hello ZF2 Test Magento (home) SugarCRM (login) Laravel Drupal 7 Drupal 8 Mediawiki Wordpress-4.1 0 0.5 1 1.5 2 2.5 3 PHP 5.6 PHP 7.0.0 HHVM 3.10.0
  • 48. Copyright - © All rights reserved. Zend Technologies, Inc.48 PHP 5 против PHP 7 против HHVM (версия Facebook)
  • 49. Copyright - © All rights reserved. Zend Technologies, Inc.49 Badoo перешли на PHP 7.0 и сэкономили $1M
  • 50. Copyright - © All rights reserved. Zend Technologies, Inc.50 Что дальше? ● PHP 7.0 ● Оптимизация структур данных ● PHP 7.1 ● Анализатор потоков данных ● Вывод типов ● Глобальный оптимизатор для байт-кода PHP ● Оптимизация и cпециализация интерпретатора
  • 51. Copyright - © All rights reserved. Zend Technologies, Inc.51 PHP 7.1 ● Уже вышел RC3 (29-го сентября 2016) ● 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()
  • 52. Copyright - © All rights reserved. Zend Technologies, Inc.52 PHP 7.1 Optimizer (script) <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 53. Copyright - © All rights reserved. Zend Technologies, Inc.53 PHP 7.1 Optimizer (bytecode) 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 RETURN $sum RETURN null <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 54. Copyright - © All rights reserved. Zend Technologies, Inc.54 PHP 7.1 Optimizer (trivial optimization) 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 RETURN $sum RETURN null <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 55. Copyright - © All rights reserved. Zend Technologies, Inc.55 PHP 7.1 Optimizer (trivial optimization) 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 RETURN $sum RETURN null <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 56. Copyright - © All rights reserved. Zend Technologies, Inc.56 PHP 7.1 Optimizer (trivial optimization) 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 RETURN $sum RETURN null <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 57. Copyright - © All rights reserved. Zend Technologies, Inc.57 PHP 7.1 Optimizer (trivial optimization) 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 RETURN $sum RETURN null <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 58. Copyright - © All rights reserved. Zend Technologies, Inc.58 PHP 7.1 Optimizer (trivial optimization) 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 RETURN $sum RETURN null <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 59. Copyright - © All rights reserved. Zend Technologies, Inc.59 PHP 7.1 Optimizer (trivial optimization) 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 RETURN $sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 60. Copyright - © All rights reserved. Zend Technologies, Inc.60 PHP 7.1 Optimizer (Control Flow Graph) 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 RETURN $sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 61. Copyright - © All rights reserved. Zend Technologies, Inc.61 PHP 7.1 Optimizer (Control Flow Graph) 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 RETURN $sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 62. Copyright - © All rights reserved. Zend Technologies, Inc.62 PHP 7.1 Optimizer (Control Flow Graph) 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 RETURN $sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 63. Copyright - © All rights reserved. Zend Technologies, Inc.63 PHP 7.1 Optimizer (Control Flow Graph) 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 RETURN $sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 64. Copyright - © All rights reserved. Zend Technologies, Inc.64 PHP 7.1 Optimizer (Static Single Assignmnt Form) 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 RETURN $?.sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 65. Copyright - © All rights reserved. Zend Technologies, Inc.65 PHP 7.1 Optimizer (Static Single Assignmnt Form) 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 RETURN $?.sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 66. Copyright - © All rights reserved. Zend Technologies, Inc.66 PHP 7.1 Optimizer (Static Single Assignmnt Form) 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 RETURN $5.sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 67. Copyright - © All rights reserved. Zend Technologies, Inc.67 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 RETURN $5.sum <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; }
  • 68. Copyright - © All rights reserved. Zend Technologies, Inc.68 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 RETURN $5.sum
  • 69. Copyright - © All rights reserved. Zend Technologies, Inc.69 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 RETURN $5.sum
  • 70. Copyright - © All rights reserved. Zend Technologies, Inc.70 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 RETURN $5.sum
  • 71. Copyright - © All rights reserved. Zend Technologies, Inc.71 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 RETURN $5.sum
  • 72. Copyright - © All rights reserved. Zend Technologies, Inc.72 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 RETURN $5.sum [long]
  • 73. Copyright - © All rights reserved. Zend Technologies, Inc.73 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 RETURN $5.sum [long]
  • 74. Copyright - © All rights reserved. Zend Technologies, Inc.74 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 RETURN $5.sum [long, double]
  • 75. Copyright - © All rights reserved. Zend Technologies, Inc.75 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 RETURN $5.sum
  • 76. Copyright - © All rights reserved. Zend Technologies, Inc.76 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..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 RETURN $5.sum [0..++]
  • 77. Copyright - © All rights reserved. Zend Technologies, Inc.77 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 RETURN $5.sum [long, double]
  • 78. Copyright - © All rights reserved. Zend Technologies, Inc.78 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 RETURN $5.sum [long, double]
  • 79. Copyright - © All rights reserved. Zend Technologies, Inc.79 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 RETURN $5.sum [long, double]
  • 80. Copyright - © All rights reserved. Zend Technologies, Inc.80 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 RETURN $5.sum [long, double]
  • 81. Copyright - © All rights reserved. Zend Technologies, Inc.81 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 RETURN $5.sum [long, double]
  • 82. Copyright - © All rights reserved. Zend Technologies, Inc.82 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 RETURN $5.sum [long, double]
  • 83. Copyright - © All rights reserved. Zend Technologies, Inc.83 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 RETURN $5.sum [long, double]
  • 84. Copyright - © All rights reserved. Zend Technologies, Inc.84 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 RETURN $5.sum [long, double]
  • 85. Copyright - © All rights reserved. Zend Technologies, Inc.85 PHP 7.1 Optimizer (final result) 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 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 RETURN $sum RETURN null
  • 86. Copyright - © All rights reserved. Zend Technologies, Inc.86 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
  • 87. Copyright - © All rights reserved. Zend Technologies, Inc.87 Что дальше? ● JIT (для PHP 7.2 или PHP 8) ● Проект стартовал в августе 2016 и находится в самом начале пути ● Для генерации машинного кода используется DynAsm из LuaJIT-2 ● https://github.com/zendtech/php-src/tree/jit-dynasm/ext/opcache/jit ● Уже сегодня ускорение на bench.php в 3 раза (в 75 раз быстрее PHP 5.0) ● На реальных приложениях ускорения нет ● Предыдущая попытка, основанная на LLVM, давала на bench.php 2.5 кратное ускорение ● На реальных приложениях была не применима (очень долго компилировала) ● https://github.com/zendtech/php-src/tree/zend-jit/ext/opcache/jit
  • 88. Copyright - © All rights reserved. Zend Technologies, Inc.88 PHP ? - JIT JIT$sum: sub $0xc, %esp mov $0x0, 0x30(%esi) mov $0x4, 0x38(%esi) mov $0x0, 0x40(%esi) mov $0x4, 0x48(%esi) jmp .L3 .L1: cmp $0x4, 0x38(%esi) jnz .L6 mov 0x30(%esi), %eax add 0x40(%esi), %eax jo .L5 mov %eax, 0x30(%esi) .L2: inc 0x40(%esi) .L3 mov $0xeca7fa64, %edi cmp $0x0, EG(vm_interrupt) jnz JIT$$interrupt_handler mov 0x40(%esi), %eax cmp $0x64, %eax jl .L1 ... $i++ $i < 100 $sum = 0 $i =0 <?php function sum() { $sum = 0; for ($i = 0; $i < 100; $i++) { $sum = $sum + $i; } return $sum; } $sum = $sum + $i
  • 89. Copyright - © All rights reserved. Zend Technologies, Inc.89 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.15.2 (--count=2) PHP/dynasm-jit 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.025 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. Старый JIT (быстрее некуда :) Новый JIT
  • 90. Confidential - © All rights reserved. Zend Technologies, Inc.90 Вопросы? Dmitry Stogov Principal Engineer at Zend Technologies @dstogov dmitry@zend.com www.zend.com
  • 91. Copyright - © All rights reserved. Zend Technologies, Inc.91 Хотите еще быстрее? – HUGE TLB или HUGE PAGE ● CPU использует виртуальную память с 4KB страницам ● CPU TLB cahce содержит всего 64-512 слотов => 256KB-2M ● TLB промахи требуют много времени для обработки ● Решение – страницы размером 2MB ● PHP-7, если может, использует 2M страницы для менеджера памяти и разделяемой памяти opcahce, где хранятся скомпилированные скрипты ● opcache.huge_tlb_caches=1 так же копирует сегмент кода в Huge Pages ● grep "Huge" /proc/meminfo AnonHugePages: 0 kB HugePages_Total: 512 HugePages_Free: 497 HugePages_Rsvd: 55 HugePages_Surp: 0 Hugepagesize: 2048 kB ● https://wiki.debian.org/Hugepages#Enabling_HugeTlbPage
  • 92. Copyright - © All rights reserved. Zend Technologies, Inc.92 Хотите еще быстрее? – 32-битная сборка? ● Почти все современные процессоры 64-битные ● Почти все современные ОС 64-битные ● X86_64 может обрабатывать данные, используя меньшее количество инструкций ● X86_64 предлагает 8 дополнительных регистров общего назначения ● Но: 64-битные адреса занимают больше места, требуют больше памяти, что ведет к увеличению промахов в CPU кэше и уменьшению производительности. ● Использование 32-битного PHP (gcc -m32 -sse2) обычно дает 5% прирост
  • 93. Copyright - © All rights reserved. Zend Technologies, Inc.93 Хотите еще быстрее? – PGO/FDO сборка ● make prof-gen ● sapi/cgi/php-cgi -T 3000 /.../wordpress/index.php > /dev/null ● make prof-clean ● make prof-use ● Скорость +8% ● Объем кода -8% (size sapi/cli/php)
  • 94. Copyright - © All rights reserved. Zend Technologies, Inc.94 Хотите еще быстрее? – opcache.file_cahe ● PHP7 opcache дает возможность дополнительно кэшировать скрипты на диске (запрещено по умолчанию) ● mkdir /tmp/opcahe ● Добавить opcache.file_cahce=/tmp/opcache в php.ini ● Уменьшает пиковые нагрузки при рестарте PHP и переполнении SHM кэша ● Улучшает время отклика в эти моменты в 2-3 раза ● Может использоваться в сценариях апгрейда (можно предварительно загрузить дисковый кэш) ● file_cache может работать вообще без SHM
  • 95. Copyright - © All rights reserved. Zend Technologies, Inc.95 Не забывайте про оптимизацию всего стека ● Оптимизация вашего PHP приложения даст наибольший результат ● Кэшируйте все, что можно ● Правильно выбирайте количество PHP процессов (больше – не значит лучше) ● MariaDB, сконфигурированная по умолчанию, замедляла Wordpress почти на 30% query_cache_size=16M query_cache_type=1 ● TCP stack ● Не отключайте Hyper-Threading