Opcache 和 JIT 编译器
Laiyong Wang Lv6

在学习GO(别问我为啥不学swoole,我喜欢简单),研究性能,发散到PHP,想到了这两个,整理下他们的大概作用和效果,具体 jit 编译引擎和 Opcache 的编译原理请谷歌……

Opcache

作用和优化领域

  1. 缓存编译的字节码

    • Opcache 的主要作用是缓存已编译的 PHP 字节码,这样 PHP 脚本在后续执行时可以直接使用缓存的字节码,而不需要再次编译。这减少了编译开销,提高了脚本的执行速度。
  2. 减少 I/O 操作

    • 通过缓存字节码,Opcache 减少了对磁盘的 I/O 操作,因为不需要每次都从文件系统读取和编译 PHP 脚本。这样可以显著提升应用程序的响应速度,特别是在 I/O 密集型的应用中。

JIT 编译器

作用和优化领域

  1. 即时编译为机器码

    • JIT 编译器在程序运行时将字节码即时编译为机器码,这样在后续的执行中可以直接运行机器码,而无需解释执行字节码。这种即时编译可以大大提高 PHP 脚本的执行效率。
  2. 优化 CPU 密集型任务

    • JIT 编译器特别适合 CPU 密集型的任务,如复杂的数学运算、科学计算、图像处理和大数据分析等。在这些任务中,JIT 可以利用运行时信息进行优化,生成高效的机器码,显著提高执行速度。

结合使用 Opcache 和 JIT

在 PHP 8 中,Opcache 和 JIT 可以结合使用,以充分利用两者的优势:

  1. Opcache 缓存字节码

    • Opcache 继续执行其缓存编译字节码的功能,这减少了编译开销和 I/O 操作,提升了 PHP 脚本的基础执行性能。
  2. JIT 编译字节码

    • JIT 编译器在 Opcache 缓存的基础上,进一步将热点字节码编译为机器码。这种结合使用使得 PHP 脚本在经过一次编译后,不仅能从缓存中读取字节码,还能即时编译为高效的机器码进行执行。

配置示例

要同时启用 Opcache 和 JIT,可以在 php.ini 文件中进行如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
; 启用 Opcache
zend_extension=opcache
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.save_comments=1

; 启用 JIT
opcache.jit_buffer_size=100M ; 分配 100 MB 内存用于 JIT
opcache.jit=tracing ; 使用 tracing 模式

适用场景

  1. Web 应用

    • 对于典型的 Web 应用,Opcache 提供了显著的性能提升,因为大多数 Web 应用是 I/O 密集型的,依赖于频繁的文件读取和编译。Opcache 可以显著减少这种开销。
  2. CPU 密集型任务

    • 对于需要进行大量计算的应用,如数据分析、图像处理或科学计算,JIT 编译器可以大大提高性能。这类任务可以从 JIT 编译器即时编译的机器码中受益。

总结

  • Opcache:通过缓存已编译的 PHP 字节码,减少了文件读取和编译的开销,主要解决 I/O 密集型任务的性能问题。
  • JIT 编译器:通过将字节码即时编译为机器码,提高了 CPU 密集型任务的执行效率。

通过结合使用 Opcache 和 JIT,PHP 8 能够在不同类型的应用中提供更高的性能,既减少了 I/O 操作的开销,又提高了计算密集型任务的执行速度。

$li-margin-bottom = 0.8rem $post-tool-button-width = 2.5rem .post-tools-container { padding-top var(--component-gap) .post-tools-list { li { margin-bottom $li-margin-bottom &:last-child { margin-bottom 0 } } li.tools-item { position relative box-sizing border-box width $post-tool-button-width height $post-tool-button-width color var(--text-color-3) font-size 1.2rem background var(--background-color-1) border-radius 50% box-shadow 2px 2px 5px var(--shadow-color) cursor pointer &:hover { box-shadow 2px 2px 8px var(--shadow-hover-color) } i { color var(--text-color-3) } &:hover { color var(--background-color-1) background var(--primary-color) i { color var(--background-color-1) !important } } &.toggle-show-toc { display none } &.go-to-comments { .post-comments-count { position absolute top 0 right -1rem display none align-items center justify-content center box-sizing border-box min-width 1.1rem height 1.1rem padding 0 0.2rem color var(--badge-color) font-size 12px background var(--badge-background-color) border-radius 0.4rem +keep-tablet() { display none !important } } } } li.status-item { width $post-tool-button-width height $post-tool-button-width color var(--text-color-3) font-size 1.6rem cursor pointer &.post-lock { cursor default .fa-lock-open { display none color var(--keep-success-color) } &.decrypt { cursor pointer .fa-lock-open { display block } .fa-lock { display none } } } } } }