Дмитрий Стогов из Zend by Perforce уже много лет работает над самым сердцем PHP и знает о нем много полезного.
Включая вопросы, связанные с производительностью.
В его отчет на конференции PHP Россия 2021 Дмитрий расскажет, как продвигается работа по JIT. А какие еще идеи повышения производительности были реализованы в PHP 8.0 и готовятся для PHP 8.1. И сегодня вы можете прочитать интервью, в котором я задавал PHP-эксперту вопросы обо всем понемногу: от его истории до обсуждения современных реалий.
— Что вы запрограммировали в первую очередь? — Еще в 80-х годах прошлого века папа познакомил меня с программируемым калькулятором «Электроника Б3-34».
В его памяти было всего 98 инструкций и 14 регистров.
Но самое главное, это было возможно.
программные игры , чем я и заинтересовался.
Я очень плотно занимался «Высадкой на Луну», даже начал брать книги по космической динамике.
Но когда я понял, что калькулятор не справляется с дифурами третьего порядка, я перешёл на электронику Д3-28. Тогда меня вдохновило написать Pac-Man, но у BASIC не было ни возможностей, ни производительности.
Я начал изучать ассемблер, и хотя я никогда не писал Pac-Man, я смог разобрать монитор и понять его внутренности.
— Когда ваше хобби начало приносить деньги? И что вы программировали в процессе? — Первые деньги я получил за работу с языком Модула-2 на PDP-11 (CM4), хотя, как я теперь понимаю, за эту работу и обучение мне пришлось доплачивать самому.
В начале 90-х, учась в Петербургском Политехникуме, я работал с командой программистов, собранной одним из преподавателей.
Нам заказали децентрализованную систему продажи квартир с серверами на VAX и удаленными терминалами на ПК, которые общаются через модем на скорости 2400 бод. Интернета в России тогда еще не было (было ФИДО), а мы уже использовали базы данных SQL и многоуровневую архитектуру.
Позже, работая системным администратором в банке и имея свободное время, я разработал компилятор Модула-2 для Linux/DOS/Windows/OS2. Тогда он был системным аналитиком в компании, занимающейся автоматизацией складской логистики.
Мы создавали складскую систему, которая управляла работниками склада.
У каждого работника был мобильный терминал со сканером штрих-кода, а на каждый стеллаж и поддон были наклеены бирки.
Система подсказала сотрудникам, куда идти, что брать, куда их отвезти.
Сейчас это никого не удивит, но в конце 90-х система с «искусственным интеллектом» выглядела чем-то нереальным.
Но она успешно распределяла поддоны по всему складу и знала, где что лежит. А еще она определила, какой поддон порвать на мелкий опт. Это была эвристическая система принятия решений, написанная на SWI Prolog. Познакомившись с внутренней структурой Пролога (Абстрактной машины Уоррена), я попытался улучшить его и написал собственный интерпретатор.
— Как вы пришли от всего этого к PHP? — В начале 2000-х я работал в немецком офисе Turck Software, где мы работали над довольно странными программами, рассчитывавшими проценты по ипотечным кредитам в немецких банках.
А потом создали простой по тем временам сервис для встраивания Гостевых книг в статические сайты.
Если я не ошибаюсь, у нас было всего 2-3 тысячи клиентов, когда мы в то время начали сталкиваться с проблемами, специфичными для PHP, и мне пришлось вникать в PHP-код. — Так появился eAccelerator? — Да, так появился Turck MMCache, который тогда конкурировал с Zend Accelerator и APC. Волей-неволей, работая над MMCache, я стал одним из экспертов по внутреннему устройству PHP, а также познакомился с ребятами из Zend. Поэтому, когда немецкий офис закрылся, я попросился в Зенд, где меня радостно встретили Зеев и Энди.
После нескольких тестовых заданий (расширения ext/soap и pecl/perl) мне разрешили исправлять ошибки в ядре PHP, а чуть позже работа по улучшению ядра была практически полностью передана мне.
Так что с 5.1 у меня стало лучше.
8.1 выйдет этой осенью.
— В чем специфика работы на PHP? — Нужно быть программистом определенного типа — компилятором.
Вот почему у меня очень хорошие отношения с ребятами, которые работают над другими языками, например над Java. Мы прекрасно понимаем друг друга, хотя говорим о совершенно разных виртуальных машинах.
Я только что работал с инженерами ARM, которые начали писать PHP JIT для своих процессоров.
Все получилось великолепно именно потому, что там тоже есть компиляторы, которые не боятся ассемблера, и мы говорим на одном языке (китайском-русском-английском).
Нам потребовалось всего пара месяцев, чтобы переписать для ARM то, что было написано для x86 за пару лет. — Это проблема, когда человек на PHP не очень понимает, что у него внутри? — Если человек пытается добавить что-то новое в PHP, но не разбирается во внутренностях, то вряд ли у него получится что-то хорошее.
Если идея хорошая, то с реализацией могу помочь я или Никита Попов.
Иногда мне приходится работать над реализацией принятых RFC, которые мне совсем не нравятся, чтобы уменьшить их негативное влияние на производительность.
Люди создают новые функции, не всегда задумываясь о том, насколько они действительно нужны.
Например, как часто вы будете использовать пересечения типов? Скорее всего, никогда, но они всегда будут тормозить (даже когда не используются).
— Можно ли сделать какие-то хитрости при реализации фич с производительностью? - Этим занимается Никита Попов.
Он часто пытается улучшить фичи, чтобы они особо не влияли на производительность хотя бы того, что написано в старом стиле.
Но оказывается, что использование этих возможностей сразу приводит к замедлению работы.
Конечно, Никита знает ядро очень хорошо, а некоторые новые места даже лучше меня.
— Есть ли какие-то глобальные планы по ядру? — У меня есть планы JIT и соединения JIT с FFI. В идеале код, написанный на PHP с использованием типов FFI, должен компилироваться так же эффективно, как код, написанный на C. Эта идея, как и многие другие, проявляется в реализации LuaJIT. — Была ли идея как-то стандартизировать опкоды, чтобы была обратная совместимость, как в той же JVM? - Нет, не было.
Здесь есть большой вопрос.
PHP не стоит на месте и постоянно меняется.
Никакие новые функции невозможны без расширения системы команд или изменения существующих.
— Получается, в вашем докладе пойдет речь не только о JIT, но и о тех хитростях, которые дают едва ли не большую производительность, чем JIT? - Да.
Ранее в этом году я потратил почти месяц на профилирование приложений на базе Symfony и наблюдение за тем, где они замедляются.
В результате я подправил алгоритмы в нескольких местах.
Где-то это были локальные нюансы реализации, где-то просто жуткие ляпы.
Нам удалось реализовать новые и довольно интересные алгоритмы.
Например, кешировать зависимости между классами, когда они объявлены в разных файлах.
На Symfony это сразу дало ускорение примерно на 10%.
И я думаю, что аналогичные улучшения будут сделаны и в других фреймворках.
Хотя WordPress практически не ускорился — классов в нем мало.
— Что-нибудь еще, что может дать большой рост? — Идеи есть, но они спорные.
Самый простой из них — теперь массивы, даже если они упакованы, хранятся в виде хеш-таблиц.
В принципе, мы могли хранить там только сами значения — zval. Для этого потребовалось бы вдвое меньше памяти, вдвое больше кэша и соответственно мы бы быстрее пробегались по массивам.
Или мы могли бы пойти еще дальше и специализировать массивы в соответствии с типами хранимых данных.
Например, массив целых чисел.
Подобные трюки реализованы в v8. Но если вы хотите конкретно оптимизировать свое приложение, вам не нужно копаться в ядре.
Поверьте, все основные тормоза закладываются в самом PHP, особенно во фреймворках, при реализации каких-то очень хитрых паттернов.
Например, я смотрю на автозагрузку в Symfony и с трудом понимаю, как она вообще работает. — Для чего еще можно использовать PHP? — Помимо веба, я использую PHP для прототипирования, чтобы быстро набросать какой-нибудь алгоритм, и при необходимости перевести его на C. Мне, например, всегда хотелось сделать простой парсер-генератор LL-грамматик с автоматическим разрешением конфликтов.
ANTLR конечно есть, но он тащит с собой много мусора.
Сейчас есть такая вещь.
Он был написан именно как прототип на PHP, но уже используется для генерации синтаксического анализатора C в PHP FFI. Конечно, в C мы могли бы использовать более оптимальные структуры данных, но в принципе классов и массивов PHP вполне достаточно для описания сложных алгоритмов на графиках и т.п.
Да, это будет работать медленнее, но вы выиграете во времени на написание и отладку.
— Была ли идея внести такие типы прямо в ядро? — Они уже в FFI. Любой тип C можно подключить и работать с PHP. Но теперь у FFI есть свои накладные расходы.
Я уже говорил об идее скрещивания FFI с JIT, чтобы избавиться от них.
— Помню, была идея написать расширение для PHP на PHP. - Теперь это реально.
Опять же, это можно сделать с помощью FFI и предварительной загрузки.
Вопрос в том, насколько это эффективно? Не многие расширения имеют хоть какое-то отношение к ядру PHP и оп-кодам: OPcache, XDebug, некоторые профилировщики.
Все остальные расширения пользовательского пространства — базы данных, JSON, XML — никак не связаны с кодами операций.
По сути, в большинстве случаев это обертки над некоторыми библиотеками, и здесь FFI может быть вполне достаточно.
Напротив, некоторые расширения написаны на C, но работают со структурами данных PHP, поэтому большого выигрыша от использования C нет. Например, тот же ext/soap. — Я слышал, что вы обсуждали с Александром Лисаченко какие-то очень интересные вопросы? - На самом деле мы давно не общались.
То, что он реализовал в PHP и FFI, конечно, очень интересно.
Непосредственно из PHP проникните в ядро, перехватите некоторый обратный вызов C и обработайте его в приложении PHP. Но реального применения этой технологии я не вижу.
Оказывается, вы можете делать с PHP в ядре все, что захотите.
А там любой чих не туда, и все у тебя развалится.
Там все основано на рефсчете.
Если вы забыли поставить ++ или - - в одном месте, то рано или поздно наступит крах.
— Возникают ли сегфолты в ядре по тем же причинам? — У каждого сегмента есть своя причина.
Но, действительно, очень часто первопричина происходящего в ядре кроется в каком-то расширении.
Например, забыли увеличить refcount при назначении, потом при выходе из какой-то процедуры появлялось двойное фри для одного принтера.
— Была ли идея сделать разработку расширений чуть более удобной для пользователя, чтобы ядро не падало и не жаловалось в таких ситуациях? Или это все существенно замедлит дело? — Нам придется полностью отказаться от существующего API. В принципе, с умными указателями C++ можно что-то сделать, автоинкремент-автодекремент. Но ядро написано на C, а не на C++.
Это добавит свои проблемы.
Ну и, конечно, будет деградация производительности.
Не обязательно серьезно.
Пока не попробуешь, не узнаешь.
И по моему опыту, не все, что хочешь попробовать, стоит доводить до конца.
Работаешь месяц, делаешь проверку концепции, дорабатываешь, понимаешь, что выиграл в производительности, но не так сильно, как усложнил систему.
Поэтому половина работы уходит в мусор.
— Что самое большое вышло в мусор? — Была идея уменьшить размер каждого значения zval до 8 байт — сейчас 16 байт. Используйте так называемую нан-тегировку, когда все хранится так, как если бы это было действительное число, а для представления типов, отличных от вещественных, используется не число (NaN).
Проще говоря, если показатель степени равен единицам, то это NaN. А в mantis можно писать все что угодно.
То есть тип кодирования, целые числа и указатели.
Это дало бы существенный прирост производительности при работе с массивами — памяти вполовину меньше, всё умещается компактнее.
- А почему этого в итоге не произошло? — Усложнение системы.
И отсутствие поддержки 64-битных целых чисел.
К сожалению, эта технология не позволяет кодировать 64-битные целые числа и усложняет доступ к указателям.
— Чего вы ожидаете от конференции?
— Для меня конференция — это возможность пообщаться.
Возможно, появятся новые идеи для реализации.
— Какой совет вы можете дать начинающему PHP-программисту, опытному и знатоку? — Для новичка мой совет: учиться, учиться и учиться.
И все же делайте это не на конференциях и курсах, а по книгам, Интернету и пособиям.
Все это дает гораздо больше, чем занятия с преподавателем, который вбивает в тебя знания, пока ты смотришь в окно и думаешь о чем-то своем.
Опытному человеку нужен отдых.
Отдыхом могут быть конференции, простая человеческая жизнь, спорт или хобби, не связанные с IT. Это нужно сделать, чтобы не превратиться в придаток к компьютеру.
Что должен сделать эксперт? Это самый трудный вопрос.
Те, кто может это сделать, учат. А в своей области не сдавайтесь и двигайтесь вперед. Двигайтесь тем, что делаете, ищите новые пути и реализации.
Или смените район, если не работает.
PHP Россия 2021 пройдет 28 июня В Москва, Рэдиссон Славянская .Теги: #Интервью #программирование #Конференции #php #конференция #php8 #phprussia #kernel #jit #jit compilerИ сегодня вы можете проверить расписание и посмотрите выступления, которые вы точно не захотите пропустить.
Офлайн-билеты распроданы.
Но вы можете принять участие онлайн.
Не забудь купить билеты сегодня!
-
Как Я Перестал Бояться И Полюбил Поддержку
19 Oct, 24 -
Для Intel Кризис Закончился
19 Oct, 24 -
Статический Api Mapbox
19 Oct, 24 -
Одноранговая База Данных :-)
19 Oct, 24 -
Судьба Отчета Об Ошибке
19 Oct, 24 -
Система Мониторинга В Bash
19 Oct, 24