PHP 8.0의 OPCache로 JIT 쓰기
PHP 8.0에 들어간 JIT의 작동 원리
PHP는 해석기(인터프리터: interpreter)를 통하여 프로그램 코드를 해석하고 번역기(컴파일러)로 기계어로 바꾸어 실행하는 인터프리터 방식으로 작동한다.
별다른 장치를 두지 않는다면, PHP 프로그램을 실행할 때마다 인터프리터(Zend VM)가 프로그램 코드를 해석하고 다시 기계어로 바꾸는 작업을 거듭하게 된다. 이 때문에 미리 기계어로 바꾸어서 실행하는 다른 프로그램들보다 실행 시간이 오래 걸리게 된다.
PHP 5.5부터 기본 모듈로 들어간 OPCache는 PHP 코드를 실행한 뒤에 인터프리터를 거친 중간 형태인 OPCode를 메모리에 담아 두고, 다음에 다시 실행할 때 디스크에 담긴 PHP 프로그램 파일이 아니라 메모리에서 OPCode를 불러 더 빠르게 실행할 수 있게 해 준다.
여기에 더하여 PHP 8.0의 OPCache에는 JIT 번역기(JIT 컴파일러)가 더해졌다. PHP 8의 JIT는 번역된 기계어를 메모리에 담아서 PHP 프로그램을 다시 부를 때 더욱 빠르게 실행할 수 있게 해 준다.
이 JIT(Just In Time)는 PHP 8이 새롭게 내세우는 주요 기능이기도 하다.
OPCache와 JIT의 작동 원리와 속도 비교 정보가 아래 글들에 설명되어 있다.
- PHP: Interpreter, OPCache, ― JIT —
- https://pronist.tistory.com/72 - PHP 8.0 JIT Is Offering Very Compelling Performance Ahead Of Its Alpha
- https://www.phoronix.com/scan.php?page=article&item=php8-jit-june&num=2 - PHP 8: JIT performance in real-life web applications
- https://www.mdeditor.tw/pl/pZgV/zh-hk - PHP 8: JIT performance in real-life web applications - stitcher.io
- https://stitcher.io/blog/jit-in-real-life-web-applications - Try out JIT compiler with PHP 8.0
- https://medium.com/jp-tech/try-out-jit-compiler-with-php-8-0-a020e6aeb3e5 - JIT Compiler in PHP 8
- https://www.droptica.com/blog/jit-compiler-php-8/
OPCache에서 JIT 설정하기
PHP 8.0에 들어간 JIT는 OPCache를 통하여 쓸 수 있다.
remi 저장소(Remi's RPM repository)를 통하여 PHP 8.0과 opcache를 깔았다면, opchache의 설정 내용을 담은 10-opcache.ini 파일이 다음 경로들 가운데 하나에 있을 것이다.
/etc/opt/remi/php80/php.d/10-opcache.ini
/etc/php-zts.d/10-opcache.ini
JIT 번역기를 쓰려면 10-opcache.ini에 아래 설정 항목을 끼워 넣거나 값을 바꿔 준다.
opcache.enable=1
opcache.jit_buffer_size=100M
opcache.jit=tracing
opcache.jit_buffer_size는 JIT 번역기가 쓸 수 있는 버퍼 메모리 크기이다. 0으로 하면 JIT 번역기가 작동하지 않는다. MB 단위로 32~100M 값이 설정 예시로 나오고 있다.
opcache.jit는 아래 설명(https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit)에 따라 숫자나 예약어로 넣을 수 있다. C, R, T, O 선택값을 합쳐서 4자리 숫자로 넣거나 tracing 또는 function로 넣을 수 있다. CRTO 숫자값으로 tracing은 1254, funciton은 1205과 같다. 기본값은 tracing이고, 1235도 권장되는 값들 가운데 하나이다.
opcache.jit string|int
For typical usage, this option accepts one of four string values:disable: Completely disabled, cannot be enabled at runtime.off: Disabled, but can be enabled at runtime.tracing/on: Use tracing JIT. Enabled by default and recommended for most users.function: Use function JIT.For advanced usage, this option accepts a 4-digit integer CRTO, where the digits mean:
- C (CPU-specific optimization flags)
- 0: Disable CPU-specific optimization.
- 1: Enable use of AVX, if the CPU supports it.
- R (register allocation)
- 0: Don't perform register allocation.
- 1: Perform block-local register allocation.
- 2: Perform global register allocation.
- T (trigger)
- 0: Compile all functions on script load.
- 1: Compile functions on first execution.
- 2: Profile functions on first request and compile the hottest functions afterwards.
- 3: Profile on the fly and compile hot functions.
- 4: Currently unused.
- 5: Use tracing JIT. Profile on the fly and compile traces for hot code segments.
- O (optimization level)
- 0: No JIT.
- 1: Minimal JIT (call standard VM handlers).
- 2: Inline VM handlers.
- 3: Use type inference.
- 4: Use call graph.
- 5: Optimize whole script.
자원이 한정된 환경에서는 딱 한 번 실행되는 코드와 함수까지 메모리에 담아 두면 역효과가 날 수도 있다. 담아 두는 정보의 폭과 담아 두는 방식을 어떻게 잡는지에 따라 JIT의 효율과 수행 속도가 조금씩 달라질 수 있다.
덧글을 달아 주세요
Magento Developer 2022/08/23 21:23 고유주소 고치기 답하기
아주 오래된 기술입니다. 2015년경에 HHVM이란 php성능향상 프로젝트가 활발했었고, 그때 HHVM으로 사이트 운영했었는데,, 엄청 빨랐죠. 다만 php코드가 지원안되는게 많아서 난관이 많았는데, 그거의 카피본이 PHP8.0입니다. 7년이란 세월이 흘러서야 이제와서 php에서도 Jit 컴파일러 도입했네요.ㅋㅋ
팥알 2022/08/28 22:45 고유주소 고치기 답하기
그렇군요. 다른 분들의 글을 찾아 보니 위키백과도 HHVM으로 운영했었다고 나오는군요.
저는 HHVM이라는 이름을 모르고 지나쳤고, 알았더라도 잘 다루었을 수준이 아니었습니다. 블로그 꾸리면서 APC나 겨우 붙여 봤고 memcache도 잘 다루지 못하는 정도였습니다.
웬만한 환경에서는 PHP 7에 들어간 opcache만 써도 PHP 8에 들어간 JIT 컴파일러까지 쓴 것과 비슷한 성능이 나오는 것 같습니다.
요즘 웹 서버들은 하드 디스크가 아니라 SSD를 쓰는 것도 겹쳐서 그런지 성능 향상 기술의 효과가 생각보다 많이 떨어지는 느낌입니다. JIT가 좋은 것도 같고 궁금했던 점을 정리해 보려고 이 글을 썼지만, JIT를 켜면 비슷한 속도에 메모리만 더 차지하는 것 같아 요즘은 꺼 두고 있습니다.^^