Bài viết được sự cho phép của tác giả Lê Chí Dũng
PHP 8: Cách thiết lập JIT
PHP 8 bổ sung một trình biên dịch JIT vào lõi của PHP có khả năng tăng tốc hiệu suất đáng kể. Có một số chú thích được thực hiện về tác động thực tế đối với các ứng dụng web trong thực tế.
Tôi cũng muốn dành một bài đăng trên blog về cách thiết lập JIT, vì có một số điều cần chia sẽ.
Thành thật mà nói, thiết lập JIT là một trong những cách cấu hình tiện ích mở rộng PHP khó hiểu nhất mà tôi từng thấy. May mắn thay, có một số phím tắt cấu hình có sẵn để dễ thiết lập hơn. Vẫn tốt để biết sâu về cấu hình JIT.
Trước hết, JIT sẽ chỉ hoạt động nếu opcache được bật, đây là mặc định cho hầu hết các cài đặt PHP, nhưng bạn nên đảm bảo rằng nó opcache.enable
được đặt thành 1 trong php.ini
tệp của bạn . Việc kích hoạt bản thân JIT được thực hiện bằng cách chỉ định opcache.jit_buffer_size
trong php.ini
.
Việc kích hoạt bản thân JIT được thực hiện bằng cách chỉ định opcache.jit_buffer_size
trong php.ini
.
Lưu ý nếu bạn đang chạy PHP qua dòng lệnh, bạn cũng có thể chuyển các tùy chọn này qua cờ -d
, thay vì thêm chúng vào php.ini
:
php -dopcache.enable=1 -dopcache.jit_buffer_size=100M
Nếu chỉ thị này bị loại trừ, giá trị mặc định được đặt thành 0 và JIT sẽ không chạy. Nếu bạn đang thử nghiệm JIT trong tập lệnh CLI, bạn sẽ cần sử dụng opcache.enable_cli
thay thế để bật opcache:
php -dopcache.enable_cli=1 -dopcache.jit_buffer_size=100M
Sự khác biệt giữa opcache.enable
và opcache.enable_cli
là cái đầu tiên nên được sử dụng nếu bạn đang chạy, chẳng hạn như máy chủ PHP tích hợp sẵn. Nếu bạn đang thực sự chạy một tập lệnh CLI, bạn sẽ cần opcache.enable_cli
.
Xem thêm php tuyển dụng nhiều vị trí trên TopDev
Trước khi tiếp tục, hãy đảm bảo JIT thực sự hoạt động, tạo một tập lệnh PHP có thể truy cập thông qua trình duyệt hoặc CLI (tùy thuộc vào nơi bạn đang thử nghiệm JIT) và xem đầu ra của opcache_get_status()
:
var_dump(opcache_get_status()['jit']);
Đầu ra sẽ giống như sau:
array:7 [
"enabled" => true
"on" => true
"kind" => 5
"opt_level" => 4
"opt_flags" => 6
"buffer_size" => 4080
"buffer_free" => 0
]
Nếu enabled
và on
đúng, bạn nên đi!
Tiếp theo, có một số cách để định cấu hình JIT (và đây là nơi chúng ta sẽ đi vào mớ hỗn độn cấu hình). Bạn có thể cấu hình khi JIT nên chạy, bao nhiêu nó nên cố gắng tối ưu hóa, vv Tất cả các tùy chọn này được cấu hình sử dụng một mục cấu hình duy nhất (!): opcache.jit
. Nó có thể trông giống như sau:
opcache.enable=1
opcache.jit=1255
Bây giờ, con số đó có nghĩa là gì? Các RFC liệt kê các nghĩa của mỗi trong số họ. Xin lưu ý bạn: đây không phải là một mặt nạ bit, mỗi số chỉ đơn giản là đại diện cho một tùy chọn cấu hình khác. RFC liệt kê các tùy chọn sau:
#O – Mức độ tối ưu hóa
0 | đừng JIT |
1 | JIT tối thiểu (gọi trình xử lý VM tiêu chuẩn) |
2 | nội tuyến trình xử lý VM chọn lọc |
3 | JIT được tối ưu hóa dựa trên suy luận kiểu tĩnh của chức năng riêng lẻ |
4 | JIT được tối ưu hóa dựa trên suy luận kiểu tĩnh và cây cuộc gọi |
5 | JIT được tối ưu hóa dựa trên suy luận kiểu tĩnh và phân tích quy trình bên trong |
#T – kích hoạt JIT
0 | JIT tất cả các chức năng khi tải tập lệnh đầu tiên |
1 | Hàm JIT trong lần thực thi đầu tiên |
2 | Hồ sơ theo yêu cầu đầu tiên và biên dịch các chức năng nóng theo yêu cầu thứ hai |
3 | Hồ sơ nhanh chóng và biên dịch các chức năng nóng |
4 | Biên dịch các hàm với thẻ @jit trong doc-comments |
5 | Truy tìm JIT |
#R – phân bổ đăng ký
0 | không thực hiện phân bổ đăng ký |
1 | sử dụng bộ cấp phát thanh ghi quét lớp lót cục bộ |
2 | sử dụng trình phân bổ thanh ghi quét lớp lót toàn cầu |
#C – cờ tối ưu hóa CPU cụ thể
0 | không ai |
1 | cho phép tạo lệnh AVX |
Dù sao, nội bộ đề xuất 1255
là mặc định tốt nhất, nó sẽ hoạt động tối đa, sử dụng JIT theo dõi, sử dụng bộ cấp phát thanh ghi quét lớp lót toàn cầu – bất kể điều gì có thể – và cho phép tạo lệnh AVX.
Vì vậy, cài đặt ini (hoặc cờ -d
) của bạn phải có các giá trị sau:
opcache.enable=1
opcache.jit_buffer_size=100M
opcache.jit=1255
Nhân tiện, hãy nhớ rằng đó opcache.jit
là tùy chọn. JIT sẽ sử dụng một giá trị mặc định nếu thuộc tính đó bị bỏ qua.
Bạn hỏi mặc định nào? Đó sẽ là opcache.jit=tracing
.
Chờ đã, đó không phải là cấu trúc giống như bitmask kỳ lạ mà chúng ta đã thấy trước đó? Đúng vậy: sau khi RFC ban đầu được thông qua, nội bộ nhận ra rằng các tùy chọn giống như bitmask-like không phải là tất cả đều thân thiện với người dùng, vì vậy họ đã thêm hai bí danh được dịch thành bitmask-like. Có opcache.jit=tracing
và opcache.jit=function
.
Sự khác biệt giữa hai chức năng này là Function JIT sẽ chỉ cố gắng tối ưu hóa mã trong phạm vi của một chức năng duy nhất, trong khi Tracing JIT có thể xem xét toàn bộ dấu vết ngăn xếp để xác định và tối ưu hóa mã nóng.
Internals khuyến nghị sử dụng Tracing JIT vì nó có thể hầu như luôn cho kết quả tốt nhất.
Vì vậy, tùy chọn duy nhất bạn thực sự cần đặt để kích hoạt JIT với cấu hình tối ưu của nó là opcache.jit_buffer_size
, nhưng nếu bạn muốn rõ ràng, danh sách opcache.jit
sẽ không phải là một ý tưởng tồi:
opcache.enable=1
opcache.jit_buffer_size=100M
opcache.jit=tracing