Низкая производительность HHVM
Я оцениваю HipHop-PHP для совместимости и производительности на нашей базе кода, но при работе с встроенным веб-сервером я получаю очень низкую производительность.
У меня есть следующая тестовая программа, которая вычисляет последовательность Фибоначчи.
ex3.php:
function fib($n)
{
if ($n <= 2)
return 1;
else
return fib($n-1) + fib($n-2);
}
$n = 36;
printf("fib(%d) = %d\n", $n, fib($n, 2));
Когда я запускаю это через HHVM с помощью командной строки, я получаю впечатляющие результаты:
time hhvm -v"Eval.Jit=true" -f ./ex3.php
fib(36) = 14930352
real 0m0.267s
user 0m0.248s
sys 0m0.020s
Сравните это со стандартным PHP:
[email protected]:/www# time php -f ./ex3.php
fib(36) = 14930352
real 0m5.606s
user 0m5.600s
sys 0m0.000s
Однако, когда я хочу включить встроенный веб-сервер в HHVM, все потери производительности теряются:
hhvm -v"Eval.Jit=true" -m server -p 8000 &
time wget -qSO - http://localhost:8000/ex3.php
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
X-Powered-By: HPHP
Date: Sat, 27 Jul 2013 14:16:09 GMT
Content-Length: 19
fib(36) = 14930352
real 0m5.279s
user 0m0.000s
sys 0m0.000s
Как вы можете видеть, я получаю ответ от HHVM, но ему требуется более 5 секунд для обработки этого запроса. Что мне не хватает?
Ответы
Ответ 1
Инженер HHVM здесь.
В режиме сервера HHVM будет запускать первые N запросов, которые он видит в режиме только для интерпретатора (т.е. при отключении JIT).
Значение по умолчанию в оптимизированной сборке равно N = 11, поэтому, если вы будете запускать запрос 12 раз, 12-й будет намного быстрее.
Вы можете настроить это с помощью опции конфигурации, например: -v Eval.JitWarmupRequests=3
. Если вы установите его на 0, вы сразу увидите ускорение.
Есть несколько причин для этого.
Во-первых, это предотвращает эффекты временного разминирования от влияния JIT-скомпилированного кода.
Например, для первых нескольких запросов может потребоваться заполнение значений в APC, что приведет к тому, что код приложения будет идти по различным путям из установившихся путей. Таким образом, мы не теряем места в компиляциях JIT, которые будут использоваться только несколько раз.
Во-вторых, он позволяет HHVM собирать профилирующие данные для улучшения будущей компиляции.
Если мы заметим, что определенное значение является целым числом в 99% случаев, например, мы можем скомпилировать код, оптимизированный для целочисленного случая. В настоящее время у нас нет возможности компилировать код JIT с включенным профилированием (сложная часть безопасно отбрасывает его, когда мы закончим с ним), поэтому мы собираем данные в режиме только для интерпретатора.
Ответ 2
У меня такая же проблема с производительностью, и я получаю впечатляющие результаты только после комментирования этих строк в файле /etc/hhvm/php.ini
;hhvm.log.level = Warning
;hhvm.log.always_log_unhandled_exceptions = true
;hhvm.log.runtime_error_reporting_level = 8191
Ответ 3
если HHVM > v3.4
Изменено
Eval.JitWarmupRequests = 0
в
Eval.JitProfileInterpRequests = 0
`#!/usr/bin/hhvm -v Eval.Jit=1 -v Eval.JitProfileInterpRequests=0 ./do.php`