zts-improvement

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

zts-improvement [2019/02/13 08:17] (current)
dmitry created
Line 1: Line 1:
 +====== PHP ZTS Improvement ======
 +
 +This is a description of ZTS improvement idea, that should reduce cost of module globals access.
 +For example EG(current_execute_data).
 +The idea came during analysing of JIT for ZTS expediency, but it should improve ZTS interpreter and whole PHP ZTS build as well.
 +
 +===== Non ZTS  Way =====
 +
 +Without ZTS this takes just 1 CPU instruction and 1 load.
 +
 +<code asm>
 + movl executor_globals+field_offset(%rip),​ %eax
 +</​code>​
 +
 +<​code>​
 +                      executor_globals
 +                      +----------------+
 +                      | field 0        |
 +  field_offset ------>| ...            |
 +                      | field N        |
 +                      +----------------+
 +</​code>​
 +
 +===== Current ZTS Way (PHP-7.3) ===== 
 +
 +However in ZTS build the same access requires 6 CPU instruction and 6 loads.
 +
 +<code asm>
 + movq _tsrm_ls_cache@gottpoff(%rip),​ %rax
 + movslq executor_globals_id(%rip),​ %rdx
 + movq %fs:​(%rax),​ %rax
 + movq (%rax),​ %rax
 + movq -8(%rax,​%rdx,​8),​ %rdx
 + movl field_offset(%rdx),​ %eax
 +</​code>​
 +
 +<​code>​
 +                           %fs
 +                            |
 +                            v       ​tsrm_tls_entry
 ++---------------------+ ​  ​+---+ ​  ​+----------------+
 +| _tsrm_ls_cache ​     |-->| + |-->| storage ​       |--+
 ++---------------------+ ​  ​+---+ ​  | count          |  |
 +                                  | thread_id ​     |  |
 +                                  | next           ​| ​ |
 +                                  +----------------+ ​ |
 +                                                      |
 ++---------------------+ ​  ​+---+ ​                      |
 +| executor_globals_id |-->| + |<​-----------+----------+ ​                           ​
 ++---------------------+ ​  ​+---+ ​           |
 +                            |              |
 +                            |       ​void** v
 +                            |     ​+----------------+
 +                            |     | slot 0         |
 +                            +---->| ...            |--+
 +                                  | slot N         ​| ​ |
 +                                  +----------------+ ​ |
 +                                                      |
 +                          +---+                       |
 +      field_offset ------>| + |<​-----------+----------+
 +                          +---+            |
 +                            |              |
 +                            |       ​EG ​    v
 +                            |     ​+----------------+
 +                            |     | field 0        |
 +                            +---->| ...            |
 +                                  | field N        |
 +                                  +----------------+
 +</​code>​
 +
 +===== New ZTS Way (PHP-7.4+ or PHP-8) =====
 +
 +In case we fatten all the data structures we may reduce access pattern to 4 instructiond and 4 loads.
 +I think, it's possible to make this changes on TSRM level only, without (or with minimal) TSRM source API modification.
 +This would allow target the improvement into PHP-7.4.
 +
 +<code asm>
 + movq _tsrm_ls_cache@gottpoff(%rip),​ %rax
 + movslq executor_globals_offset(%rip),​ %rdx
 + movq %fs:​(%rax),​ %rax
 + movq field_offset(%rax,​%rdx),​ %rax
 +</​code>​
 +
 +<​code>​
 +                           %fs
 +                            |
 +                            v       ​tsrm_tls_entry
 ++---------------------+ ​  ​+---+ ​  ​+----------------+
 +| _tsrm_ls_cache ​     |-->| + |-->| thread_id ​     |
 ++---------------------+ ​  ​+---+ ​  | next           |
 +                            |     | count          |
 +                            v     ​+----------------+
 ++---------------------+ ​  ​+---+ ​  | slot 0 size    |
 +| executor_globals_id |-->| + |-->​+----------------+
 ++---------------------+ ​  ​+---+ ​  | slot 0 field 0 |
 +                            |     | ...            |
 +                            V     | ...            |
 +                          +---+   | ...            |
 +      field_offset ------>| + |-->| ...            |
 +                          +---+   | slot 0 field N |
 +                                  +----------------+
 +                                  | ...            |
 +                                  +----------------+
 +                                  | slot K size    |
 +                                  +----------------+
 +                                  | slot K field 0 |
 +                                  | ...            |
 +                                  | slot K field M |
 +                                  +----------------+
 +</​code>​
 +
 +==== Reserved global id-s (EG, CG, etc) ====
 +
 +In addition we may reserve slots few slots for frequently used execute_data,​ compiler_data,​ etc.
 +And make "​executor_global_id"​ to be precomputed at compile time constants.
 +This will reduce access pattern to 3 instructions and 3 loads.
 +This also eliminates requirement for temporary CPU register.
 +
 +<code asm>
 + movq _tsrm_ls_cache@gottpoff(%rip),​ %rax
 + movq %fs:​(%rax),​ %rax
 + movq executor_globals_offset + field_offset(%rax),​ %rax
 +</​code>​
 +
 +==== JIT ====
 +
 +With JIT we may aviod "​position independent"​ read of "​_tsrm_ls_cache"​ and reduce access pattern to 2 instructions and 2 loads. ​
 +
 +<code asm>
 + movq %fs:​_tsrm_ls_cache,​ %rax
 + movq executor_globals_offset + field_offset(%rax),​ %rax
 +</​code>​
 +
 +Finally, we may cache address of "​tsrm_tls_entry"​ in CPU register and come to 1 instruction and 1 load.
  
zts-improvement.txt · Last modified: 2019/02/13 08:17 by dmitry