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이 새롭게 내세우는 주요 기능이기도 하다.

JIT를 내세운 PHP 8 (https://www.php.net/releases/8.0/en.php)
JIT를 내세운 PHP 8 (https://www.php.net/releases/8.0/en.php)

  OPCache와 JIT의 작동 원리와 속도 비교 정보가 아래 글들에 설명되어 있다.

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를 쓰는 효과가 오히려 줄어들기도 한다. 담아 두는 정보의 폭과 담아 두는 방식을 어떻게 잡는지에 따라 JIT의 효율과 수행 속도가 조금씩 달라질 수 있다.

2020/11/30 02:36 2020/11/30 02:36
글 걸기 주소 : 이 글에 다른 글을 걸 수 없습니다

덧글을 달아 주세요