Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
PHP 7 release
Nov 12th
* if everything goes as planned
http://hhvm.com/blog/9293/lockdown-results-and-hhvm-performance
Memory optimization
Memory optimization
• Reduce number of allocations
Memory optimization
• Reduce number of allocations
Memory
Memory optimization
• Reduce number of allocations
• PHP 5 spends 20% of CPU time in the allocator
Memory
Memory optimization
• Reduce number of allocations
• Reduce memory usage
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU L1D
1ns 32KB
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU
4ns
L2
256 K...
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU L312ns
a few...
RAM
100ns
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU L3...
RAM
100ns
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
• Less...
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Reduce indirection
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Reduce indirection
• Pointer points to pointer ...
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Reduce indirection
• Pointer points to pointer ...
Zvals: PHP 5
• Zval = Type + Value
value
ty
zval
Zvals: PHP 5
• Zval = Type + Value
value
ty
zval
$a = 42;Code:
Zvals: PHP 5
• Zval = Type + Value
value = int(42)
ty
zval *
zval
$a:
$a = 42;Code:
Zvals: PHP 5
• Zval = Type + Value
value (simple):
null, bool, int, float
ty
zval *
zval
$a:
$a = 42;Code:
Zvals: PHP 5
• Zval = Type + Value
value (complex)
ty
zval *
zval
$a:
Complex data structure:
string, array, object
$a = [...
Zvals: PHP 5
• Zval = Type + Value
value (complex)
ty
zval *
zval
$a:
Complex data structure:
string, array, object
$a = [...
Zvals: PHP 5
• Zval = Type + Value + Refcount
value (complex)
refcount = 1 ty
zval *
zval
$a:
Complex data structure:
stri...
Zvals: PHP 5
• Zval = Type + Value + Refcount
value (complex)
refcount = 2 ty
zval *
zval
$a:
Complex data structure:
stri...
Zvals: PHP 7
• Zval = Type + Value
value (complex)
ty
zval *
zval
$a:
$a = [];
$b = $a;
Code:
zval *$b:
Complex data struc...
Zvals: PHP 7
• Zval = Type + Value
zval *
zval
$a:
$a = [];
$b = $a;
Code:
zval *$b:
Complex data structure:
string, array...
value (complex)
type_info
value (complex)
type_info
Zvals: PHP 7
• Zval = Type + Value
$a:
Complex data structure:
string,...
PHP 5 PHP 7
value (simple):
null, bool, int, float
refcount ty
gc_buffer
zval * value (simple): …
type_info
1 allocations
...
PHP 5 PHP 7
value (complex)
refcount ty
gc_root
zval *
Complex data structure:
string, array, object
value (complex)
type_...
val (char *)
len (int)
A B C 0
zval value:
PHP 5
zend_string *
refcount gc_info
hash
len (size_t)
A B C 0
val (char *)
len (int)
A B C 0
zval value: zval value:
PHP 5 PHP 7
[0]: (empty)
[1]: (empty)
[2]: (empty)
[3]: (empty)
hash()
“xyz”
Arrays: PHP 5
[0]: (empty)
[1]:
[2]: (empty)
[3]: (empty)
hash()
“xyz”
data
key “xyz”
Arrays: PHP 5
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
data
key “foo”
hash()
“xyz”
data
key “xyz”
Arrays: PHP 5
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
data
key “foo”
next
data
key “bar”
next = NULL
hash()
“bar”
“xyz”
data
key “xyz”...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
hash()
“bar”
“xyz”
Arrays: PHP 5
head
tail
data
key “foo”
next
data
key “bar”
ne...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
hash()
“bar”
“xyz”
Arrays: PHP 7
data
key “foo”
next
data
key “bar”
next = NULL
...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
hash()
“bar”
“xyz”
Arrays: PHP 7
data
key “foo”
next
data
key “bar”
next = NULL
...
PHP 5 without zval PHP 7 with zval
Allocations: 2 + 1 per element 2
Size: 72 + 80 per element 56 + 36 per element
Indirect...
PHP 5 without zval PHP 7 with zval
Allocations: 2 + 1 per element 2
Size: 72 + 80 per element 56 + 36 per element
Indirect...
Immutable arrays
$arrays = [];
for ($i = 0; $i < 1000000; ++$i) {
$arrays[] = [1, 2, 3, 4, 5, 6, 7, 8];
}
Immutable arrays
$arrays = [];
for ($i = 0; $i < 1000000; ++$i) {
$arrays[] = [1, 2, 3, 4, 5, 6, 7, 8];
}
PHP 5
Memory usa...
Immutable arrays
$arrays = [];
for ($i = 0; $i < 1000000; ++$i) {
$arrays[] = [1, 2, 3, 4, 5, 6, 7, 8];
}
PHP 5 PHP 7
Memo...
Immutable arrays
$arrays = [];
for ($i = 0; $i < 1000000; ++$i) {
$arrays[] = [1, 2, 3, 4, 5, 6, 7, 8];
}
PHP 5 PHP 7 PHP ...
handle (ID)
handlers
zval value
D V ac
object
dtor()
free_storage()
clone()
handlers
refcount
gc_root
ce
properties
proper...
zend_object * refcount type_info
handle
ce
handlers
properties
value
type_info
value
type_info
value
type_info
$prop1 zval...
PHP 5 without zval PHP 7 with zval
Allocations: 2 1
Size: 96 + 8 per element 48 + 16 per element
Indirections (prop val): ...
Integers
• long  zend_long
• 64-bit integers on LLP64 platforms (= Windows)
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
<?php T_OPEN_TAG
$a T_VARIABLE
=
42 T_LNUMBER
;
$b T_VARIABLE
=
24 T_LNUMBER
;
e...
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
<?php T_OPEN_TAG
$a T_VARIABLE
=
42 T_LNUMBER
;
$b T_VARIABLE
=
24 T_LNUMBER
;
e...
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
<?php T_OPEN_TAG
$a T_VARIABLE
=
42 T_LNUMBER
;
$b T_VARIABLE
=
24 T_LNUMBER
;
e...
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
<?php T_OPEN_TAG
$a T_VARIABLE
=
42 T_LNUMBER
;
$b T_VARIABLE
=
24 T_LNUMBER
;
e...
Virtual machine
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
VM stack
INI...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
execute_data...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
execute_data...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
execute_data...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
execute_data...
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_...
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_...
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_...
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_...
Virtual machine – global registers
zend_execute_data* execute_data;
const zend_op* opline;
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* oplin...
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* oplin...
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* oplin...
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* oplin...
Opcache
Opcache
• File cache
Opcache
• File cache
• Alternative (or addition) to SHM
Opcache
• File cache
• Alternative (or addition) to SHM
• Shared hosting? PHP restart / cache reset?
Opcache
• File cache
• Alternative (or addition) to SHM
• Shared hosting? PHP restart / cache reset?
• Time for 500 sequen...
Opcache
• Huge Pages
Opcache
• Huge Pages
• Code segment of PHP binary remapped into huge pages
• Reduces iTLB misses
Opcache
• Huge Pages
• Code segment of PHP binary remapped into huge pages
• Reduces iTLB misses
CPU L2L1I …
Opcache
• Huge Pages
• Code segment of PHP binary remapped into huge pages
• Reduces iTLB misses
CPU L2L1I
L1 iTLB 4K
…
L2...
Opcache
• Huge Pages
• Code segment of PHP binary remapped into huge pages
• Reduces iTLB misses
CPU L2L1I
L1 iTLB 4K L1 i...
@nikita_ppv
nikic@php.net
https://joind.in/talk/view/15865
PHP 7 – What changed internally? (PHP Barcelona 2015)
Upcoming SlideShare
Loading in …5
×

PHP 7 – What changed internally? (PHP Barcelona 2015)

10,475 views

Published on

One of the main selling points of PHP 7 is greatly improved performance, with many real-world applications now running twice as fast… But where do these improvements come from? At the core of PHP 7 lies an engine rewrite with focus on improving memory usage and performance. This talk provides an overview of the most significant changes, briefly covering everything from data structure changes, over enhancements in the executor, to the new compiler implementation.

Published in: Technology

PHP 7 – What changed internally? (PHP Barcelona 2015)

  1. 1. PHP 7 release Nov 12th * if everything goes as planned
  2. 2. http://hhvm.com/blog/9293/lockdown-results-and-hhvm-performance
  3. 3. Memory optimization
  4. 4. Memory optimization • Reduce number of allocations
  5. 5. Memory optimization • Reduce number of allocations Memory
  6. 6. Memory optimization • Reduce number of allocations • PHP 5 spends 20% of CPU time in the allocator Memory
  7. 7. Memory optimization • Reduce number of allocations • Reduce memory usage
  8. 8. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency
  9. 9. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU
  10. 10. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU L1D 1ns 32KB
  11. 11. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU 4ns L2 256 KB L1D 1ns 32KB
  12. 12. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU L312ns a few MB 4ns L2 256 KB L1D 1ns 32KB
  13. 13. RAM 100ns Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU L312ns a few MB 4ns L2 256 KB L1D 1ns 32KB
  14. 14. RAM 100ns Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency • Less data => more fits into the cache CPU L312ns a few MB 4ns L2 256 KB L1D 1ns 32KB
  15. 15. Memory optimization • Reduce number of allocations • Reduce memory usage • Reduce indirection
  16. 16. Memory optimization • Reduce number of allocations • Reduce memory usage • Reduce indirection • Pointer points to pointer pointing to pointer pointing to pointer pointing to pointer pointing to pointer pointing to what you actually want What you have What you want
  17. 17. Memory optimization • Reduce number of allocations • Reduce memory usage • Reduce indirection • Pointer points to pointer pointing to pointer pointing to pointer pointing to pointer pointing to pointer pointing to what you actually want • Fewer memory accesses What you have What you want
  18. 18. Zvals: PHP 5 • Zval = Type + Value value ty zval
  19. 19. Zvals: PHP 5 • Zval = Type + Value value ty zval $a = 42;Code:
  20. 20. Zvals: PHP 5 • Zval = Type + Value value = int(42) ty zval * zval $a: $a = 42;Code:
  21. 21. Zvals: PHP 5 • Zval = Type + Value value (simple): null, bool, int, float ty zval * zval $a: $a = 42;Code:
  22. 22. Zvals: PHP 5 • Zval = Type + Value value (complex) ty zval * zval $a: Complex data structure: string, array, object $a = [];Code:
  23. 23. Zvals: PHP 5 • Zval = Type + Value value (complex) ty zval * zval $a: Complex data structure: string, array, object $a = []; $b = $a; Code:
  24. 24. Zvals: PHP 5 • Zval = Type + Value + Refcount value (complex) refcount = 1 ty zval * zval $a: Complex data structure: string, array, object $a = []; $b = $a; Code:
  25. 25. Zvals: PHP 5 • Zval = Type + Value + Refcount value (complex) refcount = 2 ty zval * zval $a: Complex data structure: string, array, object $a = []; $b = $a; Code: zval *$b:
  26. 26. Zvals: PHP 7 • Zval = Type + Value value (complex) ty zval * zval $a: $a = []; $b = $a; Code: zval *$b: Complex data structure: string, array, object refcount = 2
  27. 27. Zvals: PHP 7 • Zval = Type + Value zval * zval $a: $a = []; $b = $a; Code: zval *$b: Complex data structure: string, array, object refcount = 2 value (complex) type_info
  28. 28. value (complex) type_info value (complex) type_info Zvals: PHP 7 • Zval = Type + Value $a: Complex data structure: string, array, object $b: refcount = 2 zval zval
  29. 29. PHP 5 PHP 7 value (simple): null, bool, int, float refcount ty gc_buffer zval * value (simple): … type_info 1 allocations 1 level of indirection 40 bytes no allocations no indirection 16 bytes
  30. 30. PHP 5 PHP 7 value (complex) refcount ty gc_root zval * Complex data structure: string, array, object value (complex) type_info Complex data structure: string, array, object refcount gc_info 2 allocations 2 levels of indirection 40 bytes 1 allocation 1 level of indirection 24 bytes
  31. 31. val (char *) len (int) A B C 0 zval value: PHP 5
  32. 32. zend_string * refcount gc_info hash len (size_t) A B C 0 val (char *) len (int) A B C 0 zval value: zval value: PHP 5 PHP 7
  33. 33. [0]: (empty) [1]: (empty) [2]: (empty) [3]: (empty) hash() “xyz” Arrays: PHP 5
  34. 34. [0]: (empty) [1]: [2]: (empty) [3]: (empty) hash() “xyz” data key “xyz” Arrays: PHP 5
  35. 35. [0]: (empty) [1]: [2]: (empty) [3]: “foo” data key “foo” hash() “xyz” data key “xyz” Arrays: PHP 5
  36. 36. [0]: (empty) [1]: [2]: (empty) [3]: “foo” data key “foo” next data key “bar” next = NULL hash() “bar” “xyz” data key “xyz” next = NULL Arrays: PHP 5
  37. 37. [0]: (empty) [1]: [2]: (empty) [3]: “foo” hash() “bar” “xyz” Arrays: PHP 5 head tail data key “foo” next data key “bar” next = NULL data key “xyz” next = NULL
  38. 38. [0]: (empty) [1]: [2]: (empty) [3]: “foo” hash() “bar” “xyz” Arrays: PHP 7 data key “foo” next data key “bar” next = NULL data key “xyz” next = NULL
  39. 39. [0]: (empty) [1]: [2]: (empty) [3]: “foo” hash() “bar” “xyz” Arrays: PHP 7 data key “foo” next data key “bar” next = NULL data key “xyz” next = NULL Bucket * uint32_t
  40. 40. PHP 5 without zval PHP 7 with zval Allocations: 2 + 1 per element 2 Size: 72 + 80 per element 56 + 36 per element Indirections (lookup): 4 2 Arrays: comparison
  41. 41. PHP 5 without zval PHP 7 with zval Allocations: 2 + 1 per element 2 Size: 72 + 80 per element 56 + 36 per element Indirections (lookup): 4 2 PHP 5 w/ unique zvals 2 + 2 per element 72 + 112 per element 4 Arrays: comparison
  42. 42. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; }
  43. 43. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; } PHP 5 Memory usage 1336 MB Execution time (create) 0.77 s Execution time (destroy) 1.45 s
  44. 44. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; } PHP 5 PHP 7 Memory usage 1336 MB 391 MB Execution time (create) 0.77 s 0.29 s Execution time (destroy) 1.45 s 0.05 s
  45. 45. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; } PHP 5 PHP 7 PHP 7 with opcache Memory usage 1336 MB 391 MB 32 MB Execution time (create) 0.77 s 0.29 s 0.03 s Execution time (destroy) 1.45 s 0.05 s 0.002 s
  46. 46. handle (ID) handlers zval value D V ac object dtor() free_storage() clone() handlers refcount gc_root ce properties properties_table guards [0] (stores $prop1) [1] (stores $prop2) [2] (stores $prop3) zval zval zval object store bucket Zend object Objects: PHP 5
  47. 47. zend_object * refcount type_info handle ce handlers properties value type_info value type_info value type_info $prop1 zval $prop2 zval $prop3 zval Zend object Objects: PHP 7
  48. 48. PHP 5 without zval PHP 7 with zval Allocations: 2 1 Size: 96 + 8 per element 48 + 16 per element Indirections (prop val): 4 1 Objects: comparison
  49. 49. Integers • long  zend_long • 64-bit integers on LLP64 platforms (= Windows)
  50. 50. AST <?php $a = 42; $b = 24; echo $a + $b;
  51. 51. AST <?php $a = 42; $b = 24; echo $a + $b; <?php T_OPEN_TAG $a T_VARIABLE = 42 T_LNUMBER ; $b T_VARIABLE = 24 T_LNUMBER ; echo T_ECHO $a T_VARIABLE + $b T_VARIABLE ; lex
  52. 52. AST <?php $a = 42; $b = 24; echo $a + $b; <?php T_OPEN_TAG $a T_VARIABLE = 42 T_LNUMBER ; $b T_VARIABLE = 24 T_LNUMBER ; echo T_ECHO $a T_VARIABLE + $b T_VARIABLE ; ASSIGN $a 42 ASSIGN $b 24 ADD $a $b ~2 ECHO ~2 RETURN 1 lex parse + compile
  53. 53. AST <?php $a = 42; $b = 24; echo $a + $b; <?php T_OPEN_TAG $a T_VARIABLE = 42 T_LNUMBER ; $b T_VARIABLE = 24 T_LNUMBER ; echo T_ECHO $a T_VARIABLE + $b T_VARIABLE ; ASSIGN $a 42 ASSIGN $b 24 ADD $a $b ~2 ECHO ~2 RETURN 1 lex parse compile stmts assign var 42 $a assign $b echo + $a $b var 24
  54. 54. AST <?php $a = 42; $b = 24; echo $a + $b; <?php T_OPEN_TAG $a T_VARIABLE = 42 T_LNUMBER ; $b T_VARIABLE = 24 T_LNUMBER ; echo T_ECHO $a T_VARIABLE + $b T_VARIABLE ; ASSIGN $a 42 ASSIGN $b 24 ADD $a $b ~0 ECHO ~0 RETURN 1 lex parse compile token_get_all() nikic/php-ast phpdbg -p stmts assign var 42 $a assign $b echo + $a $b var 24
  55. 55. Virtual machine
  56. 56. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2);
  57. 57. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo()
  58. 58. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … VM stack
  59. 59. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … int(1) int(2) VM stack arg[0] arg[1]
  60. 60. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … int(1) int(2) execute_data VM stack arg[0] arg[1] ~0 $a $b
  61. 61. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … int(1) int(2) execute_data int(1) int(2) VM stack arg[0] arg[1] ~0 $a $b
  62. 62. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … int(1) int(2) int(3) execute_data int(1) int(2) VM stack arg[0] arg[1] ~0 $a $b
  63. 63. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … VM stack INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  64. 64. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … execute_data VM stack ~0 $a $b INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  65. 65. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … execute_data int(1) int(2) VM stack ~0 $a $b INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  66. 66. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … execute_data int(1) int(2) VM stack ~0 $a $b INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  67. 67. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … execute_data int(1) int(2) int(3) VM stack ~0 $a $b INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  68. 68. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array()
  69. 69. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array() • Only in global scope or for fully qualified calls namespace foo; echo strlen($str);
  70. 70. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array() • Only in global scope or for fully qualified calls namespace foo; echo strlen($str); Is this strlen() or foostrlen()?
  71. 71. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array() • Only in global scope or for fully qualified calls namespace foo; echo strlen($str); This is definitely strlen()!
  72. 72. Virtual machine – global registers zend_execute_data* execute_data; const zend_op* opline;
  73. 73. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15");
  74. 74. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15"); • Registers reserved in VM code
  75. 75. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15"); • Registers reserved in VM code • Avoid reloading from executor_globals / execute_data
  76. 76. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15"); • Registers reserved in VM code • Avoid reloading from executor_globals / execute_data • Avoid save/restore during calls
  77. 77. Opcache
  78. 78. Opcache • File cache
  79. 79. Opcache • File cache • Alternative (or addition) to SHM
  80. 80. Opcache • File cache • Alternative (or addition) to SHM • Shared hosting? PHP restart / cache reset?
  81. 81. Opcache • File cache • Alternative (or addition) to SHM • Shared hosting? PHP restart / cache reset? • Time for 500 sequential WP 4.1 requests SHM 3 s File cache 6 s No cache 24 s
  82. 82. Opcache • Huge Pages
  83. 83. Opcache • Huge Pages • Code segment of PHP binary remapped into huge pages • Reduces iTLB misses
  84. 84. Opcache • Huge Pages • Code segment of PHP binary remapped into huge pages • Reduces iTLB misses CPU L2L1I …
  85. 85. Opcache • Huge Pages • Code segment of PHP binary remapped into huge pages • Reduces iTLB misses CPU L2L1I L1 iTLB 4K … L2 TLB
  86. 86. Opcache • Huge Pages • Code segment of PHP binary remapped into huge pages • Reduces iTLB misses CPU L2L1I L1 iTLB 4K L1 iTLB 2M … L2 TLB
  87. 87. @nikita_ppv nikic@php.net https://joind.in/talk/view/15865

×