|
PHP / MySQL Создание динамических Веб-ресурсов |
21.07.2011, 07:00
|
#1
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Странное поведение microtime
На компьютере под Windows XP установлен PHP 5.2.17.17
Замечаю странное поведение функции microtime(). Ставил в коде метки для быстрого тестирования скорости выполнения MySQL запросов:
$time=microtime(true);
// тут код запроса, но это по сути не важно, проблема в другом
echo round(microtime(true)-$time,5);
К моему удивлению этот код считает время как ему вздумается и часто выдаёт даже отрицательные результаты. Всегда пользовался данным методом, проблем никогда не было ни на одном сервере, ни на денвере на ноутбуке (там стоит более старая версия php). Решил разобраться в чём дело, запустил многократно в консоли такой код:
$a=time();
// $a вычитается для того, чтобы убрать целую часть и видеть больше чисел после запятой
echo (microtime(true)-$a)."\r\n";
usleep(10);
echo (microtime(true)-$a)."\r\n";
usleep(10);
echo (microtime(true)-$a)."\r\n";
usleep(10);
echo (microtime(true)-$a)."\r\n";
usleep(10);
echo (microtime(true)-$a)."\r\n";
usleep(10);
echo (microtime(true)-$a)."\r\n";
usleep(10);
echo (microtime(true)-$a)."\r\n";
usleep(10);
echo (microtime(true)-$a)."\r\n";
По какой-то, неведомой мне причине, числа часто идут не в порядке возрастания, а как попало. Например число в середине списка может оказаться меньше предыдущего, а последующие опять в порядке возрастания. Или может выдать подряд штук по 5 одинаковых чисел, вплоть до миллионных долей.
Гугл в решении проблемы не помогает, так как в основном находит проблему, когда горе программисты используют функцию microtime без параметра.
Вместе с PHP тут установлен ZEND оптимизатор, не знаю имеет ли это значение, раньше никогда с ним не связывался.
Откуда PHP берёт значение microtime? У операционной системы ведь? Может XP глючит? Какие есть теории? может кто-то сталкивался с подобной проблемой.
UPD:
Всё сильнее кошу на проказы операционной системы. Запустил скрипт в консоли через интерпретатор Денвера (того, что стоит на ноутбуке и работает без нареканий), но на данном компьютере. Проблема имеет место быть. Видимо, это вопрос уже не по PHP, но всё таки, может кто-то с таким сталкивался.
|
(Offline)
|
|
21.07.2011, 09:14
|
#2
|
[object Object]
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,361
Написано 2,473 полезных сообщений (для 6,856 пользователей)
|
Ответ: Странное поведение microtime
С незапамятных времён использую следующий класс собственного написания:
class Benchmark { public $startTime = 0; public $endTime = 0; private function getmt() { //return array_sum(explode(" ", microtime())); return microtime(TRUE); } public function start() { $this->startTime = $this->getmt(); } public function stop() { $this->endTime = $this->getmt(); } public function get($round = 2) { if ($this->startTime === 0) { return ('Before using <b>' . __FUNCTION__ . '</b> , you should first start the timer!'); } return number_format(($this->endTime - $this->startTime), $round, '.', ''); } }
Испоьзование:
// require_once 'Benchmark.class.php'; $b = new Benchmark(); $b->start(); sleep(1); // sleep one second $b->stop(); echo $b->get(); // ~ 1 sec
Обрати внимание на приватный метод getmt:
private function getmt() { //return array_sum(explode(" ", microtime())); return microtime(TRUE); }
В нём 2 способа получения этого самого микротайма:
1) старый через эксплод+эрэй_сум
2) новый через флаг в микротайме
Я заметил, что на некоторых серверах второй вариант выдаёт дико неточный результат, а первый работает всегда железно, но он через-жопный (ну согласитесь, там же массивы волохаются)
Попробуй у себя 2 варианта по очереди.
Апд: Запустил твой код у себя на сервере:
0.58410406112671
0.63313007354736
0.63548994064331
0.6358630657196
0.63662004470825
0.63760709762573
0.63862204551697
0.64616799354553
|
Фурычит
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 4090 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
21.07.2011, 10:27
|
#3
|
Злобный Админ
Регистрация: 04.09.2005
Сообщений: 5,926
Написано 3,415 полезных сообщений (для 9,330 пользователей)
|
Ответ: Странное поведение microtime
Многоядерные процессоры они такие, у каждого ядра своё время
__________________
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
21.07.2011, 16:59
|
#4
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: Странное поведение microtime
Randomize, про метод с explode знал, но да, он черезжопный. Я похожий класс сам использовал ранее, тоже с explode, а потом открыл для себя Америку, что в microtime оказывается можно передавать параметр. Сейчас попробую, возможно поможет. Но использовать такое решение постоянно не хочется.
SBJoker, при запуске PHP скрипта в консоли, он никогда у меня в диспетчере задач не отбирает более 50% процессора, поэтому я делаю вывод, что PHP во время выполнения юзает только одно ядро (на машине двухядерный процессор).
|
(Offline)
|
|
21.07.2011, 17:20
|
#5
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: Странное поведение microtime
Протестировал вариант с array_sum(explode(" ", microtime()));
Выдаёт всё равно какие попало числа:
0.689378976822
0.689965963364
0.690943002701
1.8727850914
0.704999923706
0.704999923706
0.704999923706
0.704999923706
|
(Offline)
|
|
21.07.2011, 17:30
|
#6
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: Странное поведение microtime
На форуме softtime человек высказал предположение, что это совместный глюк Windows API и PHP засчёт того, что таймеры в винде итак не точные, а ещё и PHP тормозит. Я ответил:
Возможно данная проблема проявляется всегда, просто в настолько небольшой степени, что это незаметно. Разница в тысячную долю секунду особо большой роли не сыграет. Но у меня разница достигает более одной секунды иногда. Это ни в какие рамки не лезет. На компе проц AMD, на ноуте Intel. На обоих стоит WINDOWS XP с одного и того же физического носителя. Автообновление включено на обоих. Но раньше на компе стояла эта же винда и тот же самый интерпретатор и проблемы не было насколько я помню (не думаю, что она бы прошла у меня мимо глаз). Поэтому я сейчас думаю, что тут какая-то проблема с конфигурацией системы (я тут в винде понаотключал ненужных сервисов, в реестре менял некоторые вещи, но не думаю, что я задел что-то такое, что может влиять на время).
|
|
(Offline)
|
|
21.07.2011, 22:39
|
#7
|
Злобный Админ
Регистрация: 04.09.2005
Сообщений: 5,926
Написано 3,415 полезных сообщений (для 9,330 пользователей)
|
Ответ: Странное поведение microtime
Сообщение от Phantom
Randomize, про метод с explode знал, но да, он черезжопный. Я похожий класс сам использовал ранее, тоже с explode, а потом открыл для себя Америку, что в microtime оказывается можно передавать параметр. Сейчас попробую, возможно поможет. Но использовать такое решение постоянно не хочется.
SBJoker, при запуске PHP скрипта в консоли, он никогда у меня в диспетчере задач не отбирает более 50% процессора, поэтому я делаю вывод, что PHP во время выполнения юзает только одно ядро (на машине двухядерный процессор).
|
Ты непонял меня.
Я и неговорил что пхп исполняется многопоточно. Дело в том что отдавая команду "поспать" процессу ты выводишь его из очереди на выполнение, и в следующий раз он может быть с 50% вероятностью для двухядерного процессора исполнен другим ядром. А время ядер никогда не совпадает так точно.
__________________
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо SBJoker за это полезное сообщение:
|
|
21.07.2011, 22:53
|
#8
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: Странное поведение microtime
Проблема возникает, даже без использования sleep и usleep.
Как можно решить эту проблему, если это она? Почему другие компы работают нормально? Я и раньше работал за этим компом, но это было давно, с тех пор там в нём много чего менялось, но процессор прежний. Раньше проблемы либо не было, либо я её не замечал (что маловероятно).
UPD:
Может можно как-то без негативных последствий отключить временно одно ядро и проверить останется проблема или нет?
|
(Offline)
|
|
22.07.2011, 19:40
|
#9
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: Странное поведение microtime
Думаю, что дальнейшее обсуждение проблемы продолжу на форуме Softtime, там поактивнее люди обсуждают. Кому интересно, вот ссылка: http://softtime.ru/forum/read.php?id...id_theme=81781
Когда решу проблему, решение напишу и тут.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
22.07.2011, 23:46
|
#10
|
Мастер
Регистрация: 03.05.2010
Адрес: Подмосковье
Сообщений: 1,218
Написано 438 полезных сообщений (для 790 пользователей)
|
Ответ: Странное поведение microtime
Может можно как-то без негативных последствий отключить временно одно ядро и проверить останется проблема или нет?
|
Win 7: диспетчер задач>процессы>задать соответствие
__________________
О¯О ¡¡¡ʁɔvʎнdǝʚǝdǝu dиW
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
23.07.2011, 16:24
|
#11
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: Странное поведение microtime
Win 7: диспетчер задач>процессы>задать соответствие
|
Уже провёл тесты. Судя по всему Джокер был прав. Если заставить PHP или Апач выполняться только одним из ядер, не важно каким, то проблема не проявляется вообще. Кроме того, чем дольше комп работает, тем время между ядрами рассинхронизуется всё сильнее и сильнее. Вот комп поработал несколько дней без выключения, так время вообще на 2 секунды уплыло. Прошил биос, уменьшил даже тактовую частоту с 2.300 до 2.200, сменил параметр оверклокинга с авто на стандарт. Не помогает, время всё равно спустя час работы компа "уплывает", но вроде немного медленнее, чем обычно. Может можно где-то в винде задать, через какое ядро ему время считать? Или как вариант, возможно, винда должна проводить какую-то синхронизацию между ядрами постоянно, но не делает этого из-за глюка/сбитых_настроек? Или что-то в этом роде?
Конфигурация компьютера:
Система:
Microsoft Windows XP Professional версия 2002 Service Pack 3
Компьютер:
AMD Athlon(tm) 64 X2 Dual Core Processor 4400+ 2.31 ГГц (уже 2.21 после смены настроек Биоса), 1.00 ГБ ОЗУ
|
(Offline)
|
|
10.08.2011, 12:19
|
#12
|
Элита
Регистрация: 14.06.2008
Адрес: Украина, Киев
Сообщений: 2,273
Написано 754 полезных сообщений (для 1,833 пользователей)
|
Ответ: Странное поведение microtime
В общем, вот решение проблемы от самого Майкрософта: http://support.microsoft.com/kb/895980/
Хотя там оно заявлено как "временное", то есть костыль. Но всё работает и глюков не заметил в течении 2 с половиной недель использования.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо Phantom за это полезное сообщение:
|
|
10.08.2011, 12:51
|
#13
|
[object Object]
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,361
Написано 2,473 полезных сообщений (для 6,856 пользователей)
|
Ответ: Странное поведение microtime
Спасибо! Буду иметь в виду.
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 4090 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
|
(Offline)
|
|
26.01.2012, 00:09
|
#14
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: Странное поведение microtime
Сообщение от SBJoker
Ты непонял меня.
Я и неговорил что пхп исполняется многопоточно. Дело в том что отдавая команду "поспать" процессу ты выводишь его из очереди на выполнение, и в следующий раз он может быть с 50% вероятностью для двухядерного процессора исполнен другим ядром. А время ядер никогда не совпадает так точно.
|
Прошу извинить за придирку и откапывание старых тем, но, возможно, это будет кому-то полезно.
Из книги Дж. Рихтера Windows для профессионалов: создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows/Пер, англ - 4-е изд. - СПб; Питер; М.: Издательско-торговый дом "Русская Редакция", 2001. - 752 с.; ил.
По умолчанию Windows 2000 использует нежесткую привязку (soft affmity) потоков к процессорам. Это означает, что при прочих равных условиях, система пытается выполнять поток на том же процессоре, на котором он работал в последний раз. При таком подходе можно повторно использовать данные, все еще хранящиеся в кэше процессора
|
Т.е., в общем случае, 50% - завышенная оценка.
В остальном - Джокер первым верно указал проблему.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
26.01.2012, 18:13
|
#15
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: Странное поведение microtime
Прошу прощения ещё раз, но
Сообщение от SBJoker
А время ядер никогда не совпадает так точно.
|
Основная проблема всё же в том, что у разных ядер может быть разная, не равная номинальной частота, как следствие - разная производительность в тактах и разная скорость течения времени (если это не контролируется программой BIOS и дровами). Причина отличия частоты от номинала - технологии:
понижения частоты ядер AMD Cool'n'Quiet и Intel SpeedStep,
повышения частоты ядер AMD Turbo Core и Intel Turbo Boost.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо impersonalis за это полезное сообщение:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 14:36.
|