PHP GetRusage () Возвращая неверная информация?
-
02-10-2019 - |
Вопрос
Я пытаюсь определить использование CPU моих сценариев PHP. Я только что нашел эта статья Какие подробности о том, как найти время использования системы и пользователя CPU (раздел 4).
Однако, когда я попробовал примеры, я получил совершенно разные результаты.
То первый пример:
sleep(3);
$data = getrusage();
echo "User time: ".
($data['ru_utime.tv_sec'] +
$data['ru_utime.tv_usec'] / 1000000);
echo "System time: ".
($data['ru_stime.tv_sec'] +
$data['ru_stime.tv_usec'] / 1000000);
Результаты в:
User time: 29.53
System time: 2.71
Пример 2.:
for($i=0;$i<10000000;$i++) {
}
// Same echo statements
Результаты:
User time: 16.69
System time: 2.1
Пример 3.:
$start = microtime(true);
while(microtime(true) - $start < 3) {
}
// Same echo statements
Результаты:
User time: 34.94
System time: 3.14
Очевидно, ни одна информация не является правильной За исключением, возможно, системное время в третьем примере. Так что я делаю не так? Мне очень хотелось бы использовать эту информацию, но она должна быть надежной.
Я использую Ubuntu Server 8.04 LTS (32-битный), и это вывод php -v
:
PHP 5.2.4-2ubuntu5.10 with Suhosin-Patch 0.9.6.2 (cli) (built: Jan 6 2010 22:01:14)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
Решение
Вы можете использовать команду системы «Время», чтобы проверить эту информацию извне:
/usr/bin/time php script.php
который будет напечатать что-то вроде:
0.03user 0.00system 0:03.04elapsed 0%CPU (0avgtext+0avgdata 32752maxresident)k
0inputs+0outputs (0major+2234minor)pagefaults 0swaps
Конечно, не забудьте, что используемая информация GetRusage () используется и Microtime () - это настенное время. Программа может работать в течение 10 минут в соответствии с часами на стене, но внутренне могут использовать только несколько секунд процессора. Тогда есть борьба на процессорное время со всеми фоновыми программами, работающими на системе, разумное соперничество в ресурсах плюс регулярное уборку.
Есть слишком много факторов, которые могут быть в состоянии получить точное время для таких коротких периодов. Делать три пробега while(microtime())
Версия вашего цикла, я получил следующие сроки:
Пользователь: 0,98, 0,09, 0,90 sys: 0,12, 0,05, 0,94
Очевидно, совсем дисперсия. Даже просто простой <? print_r(getrusage()) ?>
Имеет UTIME / stimes от 0 до 0,03.
Попробуйте запускать свои петли на более длительные периоды и сделайте что-то внутри, чтобы увеличить использование ЦП. Прямо сейчас ваши номера слишком малы, чтобы точно измерить.
Другие советы
Благодаря Совет Marc B, Я смог выяснить, что смехотворно короткие времена вызывали ошибки в getrusage()
расчеты.
Я создал работу, чтобы отбросить эти неточные числа. Вот код:
define('SCRIPT_START', microtime(1));
register_shutdown_function('record_activity');
/* Do work here */
function record_activity()
{
$data = getrusage();
$cpuu = ($data['ru_utime.tv_sec'] + $data['ru_utime.tv_usec'] / 1000000);
$cpus = ($data['ru_stime.tv_sec'] + $data['ru_stime.tv_usec'] / 1000000);
$renderedtime = round(microtime(1) - SCRIPT_START, 6);
// Have some log function to put this info somewhere
insert_record($renderedtime,
//Only pass user CPU time if it's less than or equal to rendered time
($renderedtime >= $cpuu ? $cpuu : NULL ),
//Only pass system CPU time if it's less than or equal to rendered time
($renderedtime >= $cpus ? $cpus : NULL ));
}
Надеюсь, это будет полезно для кого-либо еще, кто испытывает ту же проблему.