SlideShare a Scribd company logo
PHP 7 – What changed internally? (PHP Barcelona 2015)
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 KB
L1D
1ns 32KB
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
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
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
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 pointing to pointer pointing to pointer pointing to
pointer pointing to pointer pointing to what you actually want
What you
have
What you
want
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
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 = [];Code:
Zvals: PHP 5
• Zval = Type + Value
value (complex)
ty
zval *
zval
$a:
Complex data structure:
string, array, object
$a = [];
$b = $a;
Code:
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:
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:
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
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
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
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
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
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”
next = NULL
Arrays: PHP 5
[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
[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
[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
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
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
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 usage 1336 MB
Execution time (create) 0.77 s
Execution time (destroy) 1.45 s
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
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
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
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
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
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
;
echo T_ECHO
$a T_VARIABLE
+
$b T_VARIABLE
;
lex
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
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
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
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_FCALL foo
RECV $a
RECV $b
ADD $a $b ~0
RETURN ~0
{main}
foo()
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
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]
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
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
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
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
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
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
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
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
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_func()
• call_user_func_array()
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);
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()?
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()!
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* opline __asm__("%r15");
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* opline __asm__("%r15");
• Registers reserved in VM code
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
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
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 sequential WP 4.1 requests
SHM 3 s
File cache 6 s
No cache 24 s
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 TLB
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
@nikita_ppv
nikic@php.net
https://joind.in/talk/view/15865

More Related Content

PDF
200 mcq c++(Ankit dubey)
PDF
MySQL Index Cookbook
PDF
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
PDF
PHP Unit 4 arrays
PDF
Streaming Operational Data with MariaDB MaxScale
PPT
Advanced Sql Injection ENG
PDF
Just-In-Time Compiler in PHP 8
PDF
Advanced MySQL Query Tuning
200 mcq c++(Ankit dubey)
MySQL Index Cookbook
Query Optimization with MySQL 5.7 and MariaDB 10: Even newer tricks
PHP Unit 4 arrays
Streaming Operational Data with MariaDB MaxScale
Advanced Sql Injection ENG
Just-In-Time Compiler in PHP 8
Advanced MySQL Query Tuning

What's hot (20)

PDF
Typed Properties and more: What's coming in PHP 7.4?
PDF
HTTP Parameter Pollution Vulnerabilities in Web Applications (Black Hat EU 2011)
PDF
Pwning in c++ (basic)
PDF
Enterprise Manager: Write powerful scripts with EMCLI
PDF
From Postgres to ScyllaDB: Migration Strategies and Performance Gains
PDF
PHP 7 – What changed internally?
PDF
MySQL Storage Engines
PDF
Using MongoDB as a high performance graph database
PDF
Message Queue 가용성, 신뢰성을 위한 RabbitMQ Server, Client 구성
PDF
MongoDB .local Toronto 2019: Tips and Tricks for Effective Indexing
PDF
Sql query patterns, optimized
PPT
PHP - Introduction to PHP AJAX
PDF
How to Design Indexes, Really
PDF
Linux SMEP bypass techniques
PDF
Mvcc in postgreSQL 권건우
PPTX
Ettercap
PPTX
Apache Flink Hands On
PPTX
Implementing a JavaScript Engine
PPT
Html & CSS - Best practices 2-hour-workshop
PDF
InnoDB Architecture and Performance Optimization, Peter Zaitsev
Typed Properties and more: What's coming in PHP 7.4?
HTTP Parameter Pollution Vulnerabilities in Web Applications (Black Hat EU 2011)
Pwning in c++ (basic)
Enterprise Manager: Write powerful scripts with EMCLI
From Postgres to ScyllaDB: Migration Strategies and Performance Gains
PHP 7 – What changed internally?
MySQL Storage Engines
Using MongoDB as a high performance graph database
Message Queue 가용성, 신뢰성을 위한 RabbitMQ Server, Client 구성
MongoDB .local Toronto 2019: Tips and Tricks for Effective Indexing
Sql query patterns, optimized
PHP - Introduction to PHP AJAX
How to Design Indexes, Really
Linux SMEP bypass techniques
Mvcc in postgreSQL 권건우
Ettercap
Apache Flink Hands On
Implementing a JavaScript Engine
Html & CSS - Best practices 2-hour-workshop
InnoDB Architecture and Performance Optimization, Peter Zaitsev
Ad

Similar to PHP 7 – What changed internally? (PHP Barcelona 2015) (20)

PDF
PHP 7 – What changed internally? (Forum PHP 2015)
PDF
The secret of PHP7's Performance
PDF
Symfony live 2017_php7_performances
PPTX
PHP in 2018 - Q1 - AFUP Limoges
PDF
Profiling php5 to php7
PDF
PHP 7 performances from PHP 5
PDF
SymfonyCon 2017 php7 performances
PDF
"Развитие ветки PHP-7"
PDF
PHP7 - The New Engine for old good train
PDF
Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...
PPTX
Php Extensions for Dummies
PDF
PHPConPl 2013 - Allowed memory size of X bytes exhausted
ODP
Php in 2013 (Web-5 2013 conference)
PDF
ElePHPant7 - Introduction to PHP7
PDF
PHP Performance Trivia
PPTX
PHP7 Presentation
PPTX
PHP in 2018 - Q4 - AFUP Limoges
PPTX
Php 7 hhvm and co
PDF
Overview changes in PHP 5.4
PHP 7 – What changed internally? (Forum PHP 2015)
The secret of PHP7's Performance
Symfony live 2017_php7_performances
PHP in 2018 - Q1 - AFUP Limoges
Profiling php5 to php7
PHP 7 performances from PHP 5
SymfonyCon 2017 php7 performances
"Развитие ветки PHP-7"
PHP7 - The New Engine for old good train
Как мы сделали PHP 7 в два раза быстрее PHP 5 / Дмитрий Стогов (Zend Technolo...
Php Extensions for Dummies
PHPConPl 2013 - Allowed memory size of X bytes exhausted
Php in 2013 (Web-5 2013 conference)
ElePHPant7 - Introduction to PHP7
PHP Performance Trivia
PHP7 Presentation
PHP in 2018 - Q4 - AFUP Limoges
Php 7 hhvm and co
Overview changes in PHP 5.4
Ad

More from Nikita Popov (6)

PDF
A whirlwind tour of the LLVM optimizer
PDF
Opaque Pointers Are Coming
PDF
What's new in PHP 8.0?
PDF
What's new in PHP 8.0?
PDF
Static Optimization of PHP bytecode (PHPSC 2017)
PDF
PHP Language Trivia
A whirlwind tour of the LLVM optimizer
Opaque Pointers Are Coming
What's new in PHP 8.0?
What's new in PHP 8.0?
Static Optimization of PHP bytecode (PHPSC 2017)
PHP Language Trivia

Recently uploaded (20)

PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
Machine Learning_overview_presentation.pptx
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Machine learning based COVID-19 study performance prediction
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Electronic commerce courselecture one. Pdf
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
The AUB Centre for AI in Media Proposal.docx
Machine Learning_overview_presentation.pptx
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
sap open course for s4hana steps from ECC to s4
Network Security Unit 5.pdf for BCA BBA.
20250228 LYD VKU AI Blended-Learning.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
MIND Revenue Release Quarter 2 2025 Press Release
Machine learning based COVID-19 study performance prediction
Spectral efficient network and resource selection model in 5G networks
Electronic commerce courselecture one. Pdf
Chapter 3 Spatial Domain Image Processing.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
Per capita expenditure prediction using model stacking based on satellite ima...

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

  • 2. PHP 7 release Nov 12th * if everything goes as planned
  • 5. Memory optimization • Reduce number of allocations
  • 6. Memory optimization • Reduce number of allocations Memory
  • 7. Memory optimization • Reduce number of allocations • PHP 5 spends 20% of CPU time in the allocator Memory
  • 8. Memory optimization • Reduce number of allocations • Reduce memory usage
  • 9. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency
  • 10. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU
  • 11. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU L1D 1ns 32KB
  • 12. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU 4ns L2 256 KB L1D 1ns 32KB
  • 13. 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. 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
  • 15. 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
  • 16. Memory optimization • Reduce number of allocations • Reduce memory usage • Reduce indirection
  • 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 What you have What you want
  • 18. 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
  • 19. Zvals: PHP 5 • Zval = Type + Value value ty zval
  • 20. Zvals: PHP 5 • Zval = Type + Value value ty zval $a = 42;Code:
  • 21. Zvals: PHP 5 • Zval = Type + Value value = int(42) ty zval * zval $a: $a = 42;Code:
  • 22. Zvals: PHP 5 • Zval = Type + Value value (simple): null, bool, int, float ty zval * zval $a: $a = 42;Code:
  • 23. Zvals: PHP 5 • Zval = Type + Value value (complex) ty zval * zval $a: Complex data structure: string, array, object $a = [];Code:
  • 24. Zvals: PHP 5 • Zval = Type + Value value (complex) ty zval * zval $a: Complex data structure: string, array, object $a = []; $b = $a; Code:
  • 25. 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:
  • 26. 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:
  • 27. 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
  • 28. 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
  • 29. 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
  • 30. 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
  • 31. 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
  • 32. val (char *) len (int) A B C 0 zval value: PHP 5
  • 33. 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
  • 34. [0]: (empty) [1]: (empty) [2]: (empty) [3]: (empty) hash() “xyz” Arrays: PHP 5
  • 35. [0]: (empty) [1]: [2]: (empty) [3]: (empty) hash() “xyz” data key “xyz” Arrays: PHP 5
  • 36. [0]: (empty) [1]: [2]: (empty) [3]: “foo” data key “foo” hash() “xyz” data key “xyz” Arrays: PHP 5
  • 37. [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
  • 38. [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
  • 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
  • 40. [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
  • 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 Arrays: comparison
  • 42. 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
  • 43. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; }
  • 44. 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
  • 45. 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
  • 46. 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
  • 47. 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
  • 48. 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
  • 49. 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
  • 50. Integers • long  zend_long • 64-bit integers on LLP64 platforms (= Windows)
  • 51. AST <?php $a = 42; $b = 24; echo $a + $b;
  • 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 ; lex
  • 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
  • 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 ~2 ECHO ~2 RETURN 1 lex parse compile stmts assign var 42 $a assign $b echo + $a $b var 24
  • 55. 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
  • 57. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2);
  • 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()
  • 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() … VM stack
  • 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) VM stack arg[0] arg[1]
  • 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 VM stack arg[0] arg[1] ~0 $a $b
  • 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) execute_data int(1) int(2) VM stack arg[0] arg[1] ~0 $a $b
  • 63. 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
  • 64. 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
  • 65. 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
  • 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. 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
  • 68. 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
  • 69. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array()
  • 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);
  • 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); Is this strlen() or foostrlen()?
  • 72. 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()!
  • 73. Virtual machine – global registers zend_execute_data* execute_data; const zend_op* opline;
  • 74. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15");
  • 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
  • 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
  • 77. 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
  • 80. Opcache • File cache • Alternative (or addition) to SHM
  • 81. Opcache • File cache • Alternative (or addition) to SHM • Shared hosting? PHP restart / cache reset?
  • 82. 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
  • 84. Opcache • Huge Pages • Code segment of PHP binary remapped into huge pages • Reduces iTLB misses
  • 85. Opcache • Huge Pages • Code segment of PHP binary remapped into huge pages • Reduces iTLB misses CPU L2L1I …
  • 86. Opcache • Huge Pages • Code segment of PHP binary remapped into huge pages • Reduces iTLB misses CPU L2L1I L1 iTLB 4K … L2 TLB
  • 87. 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