php / php/php-src

Function `zend_hash_find_bucket` consumes much time in WordPress workload

Open
#12,873 13 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Category: Engine
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

Description

Dear, maintainers:
I am utilizing PHP-FPM and have profiled performance data for a WordPress workload. Within this benchmark, I've identified certain hotspots. The performance analysis from 'perf' highlights that functions such as zend_hash_find and zend_hash_find_known_hash are consuming a considerable amount of time. Upon investigation, I suspect that the core issue lies within the zend_hash_find_bucket function.
image

Upon inspecting the assembly code and annotating it, I noticed that certain 'mov' instructions are causing significant delays. To address this, I attempted to optimize the zend_hash_find_bucket function. I experimented with optimizations such as utilizing prefetch instructions and employing struct alignment. However, these optimizations did not seem to have a discernible impact on performance.

Percent│
       │
       │
       │    Disassembly of section .text:
       │
       │    0000000000532ae0 <zend_hash_find>:
       │    zend_hash_find():
  0.84 │      push %r12
  0.04 │      push %rbp
  0.01 │      mov  %rsi,%rbp
  2.52 │      push %rbx
       │    zend_string_hash_val():
  8.01 │      mov  0x8(%rsi),%rax
       │    zend_hash_find():
  0.02 │      mov  %rdi,%rbx
       │    zend_string_hash_val():
  0.12 │      test %rax,%rax
  0.14 │    ↓ je   78
       │    zend_hash_find_bucket():
  5.63 │13:   or   0xc(%rbx),%eax
  0.28 │      mov  0x10(%rbx),%r12
  0.16 │      cltq
 25.03 │      mov  (%r12,%rax,4),%ebx
  1.98 │      cmp  $0xffffffff,%ebx
  0.56 │    ↓ je   a0
  0.85 │      shl  $0x5,%rbx
  0.50 │      add  %r12,%rbx
 15.20 │      cmp  0x18(%rbx),%rbp
 12.97 │    ↓ jne  68
       │    zend_hash_find():
  1.41 │32:   mov  %rbx,%rax
  0.60 │      pop  %rbx
  0.03 │      pop  %rbp
  1.25 │      pop  %r12
  1.83 │    ← ret
       │      nop
       │    zend_hash_find_bucket():
  0.26 │40:   mov  0x18(%rbx),%rdi
  0.04 │      test %rdi,%rdi
       │    ↓ je   53
       │    zend_string_equal_content():
  0.01 │      mov  0x10(%rbp),%rax
  0.01 │      cmp  %rax,0x10(%rdi)
  5.03 │    ↓ je   90
       │    zend_hash_find_bucket():
  1.06 │53:   mov  0xc(%rbx),%ebx
  0.11 │      cmp  $0xffffffff,%ebx
  0.15 │    ↓ je   a0
  0.33 │      shl  $0x5,%rbx
  0.24 │      add  %r12,%rbx
  1.90 │      cmp  0x18(%rbx),%rbp
  2.69 │    ↑ je   32
  2.00 │68:   mov  0x8(%rbp),%rax
  0.24 │      cmp  %rax,0x10(%rbx)

Is this a known performance issue within the PHP community? I'm seeking suggestions or insights on potential avenues for optimization. Your feedback and suggestions would be greatly appreciated.

PHP Version

master

Operating System

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading zend_hash_find_bucket and the related zend_hash_find and zend_hash_find_known_hash entry points, then reproduce the reported perf profile against the WordPress workload. Done requires a justified change with measurable improvement in that workload, while preserving hash lookup behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, php
Domain
backend, performance
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.