«Нужно лишь аккуратно сгенерировать LLVM IR». Егор Богатов о Mono и .NET Core

-t2-ih1ivohzc1h8swwc78vx0qq.jpegЕгор Богатов — разработчик в Microsoft из команды Mono, который работает над Mono и объединяет его с .NET Core. Мы пообщались с ним о том, как работать внутри Xamarin и Microsoft, о любви к геймдеву. Обсудили, почему SSD — лучший друг разработчика, а польза докладов на конференциях не всегда соотносится с их сложностью.

Знакомство: о шифрованных демках и том, как попал в Xamarin


— Давай расскажем Хабру, кто ты, чем занимаешься.

— Я разработчик, уже лет десять работаю в стеке .NET, немножко работал в Java и совсем немного писал под Android.

Работал в разных компаниях: начинал с аутсорса, потом перешел в продуктовые, такие как Viber и Playtika. Потом я немножко пофрилансил, в том числе на Java, и пошел работать в Xamarin.

— Как ты туда попал?

— Я очень давно увлекался .NET и Mono. Мне нравился C#, но не нравилась политика Microsoft, которая его сильно завязала на Windows. Поэтому я следил за кроссплатформенной реализацией с момента ее появления.

Я активно следил за Mono, за Xamarin, как только он появился: мне нравилась сама концепция. Участвовал в их конкурсах и несколько раз занимал вторые места. Меня заметили и предложили поработать контрактором, причем написал сам Мигель де Икаса, что стало для меня полной неожиданностью, ведь для меня он был человеком-легендой.

— С чего ты начинал?

— Мигель предложил мне написать демо, которое включало в себя чат с end-to-end шифрованием под мобильные платформы. У меня был опыт работы с чат-приложениями и я увлекался темой шифрования, поэтому изначально меня взяли на бэкенд, но я сказал, что могу разрабатывать и под Android. После этого я занимался разными сторонними проектами Xamarin — меня не пускали в runtime и сами компоненты.

У Мигеля много интересных проектов. Иногда мне кажется, что это группа людей под одним именем. Ну не может один человек во всем шарить, всем отвечать, быть в курсе всего.

Я несколько раз делал для него демо для больших конференций типа Xamarin Evolve и MS Build — это самая большая девелоперская конфа у Microsoft.

А в чем была их коммерческая значимость этих демо, для чего они нужны?

Просто реклама технологии среди потенциальных клиентов. К примеру, одно из демо показывало пример как можно легко встроить 3D-визуализацию в обычное приложение на любой платформе и эта возможность заинтересовала несколько серьезных компаний в этой области.

О работе: задачи и вечный спор «удалёнка или офис»


— А теперь чем занимаешься?

— Меня перевели в команду runtime, то есть непосредственно в Mono. Моя главная обязанность — это мержить Mono и .NET Core, то есть быть где-то между двумя рантаймами. Это позволяет мне лучше понимать .NET, потому что я все эти типы, начиная с самых базовых и заканчивая сложными, исследую и досконально рассматриваю. За два года удалось нарастить хорошую базу опыта и познакомиться со всеми ключевыми разработчиками.

— Ты работаешь из дома?

— У нас есть небольшой офис Microsoft в Минске. Я периодически туда наведываюсь, но в основном из дома работаю.

— А что лучше: работать в офисе или дома?

— Для работы дома нужна большая самодисциплина. Периодически пробую совмещать это с путешествиями, но выходит не слишком эффективно. Мне, например, нужен полноценный здоровый десктопный комп с тремя мониторами. На ноутбуке я не могу комфортно работать.

— Тебе это нужно именно для мониторов или важна мощность компа?

— И для мониторов, и для мощности. Мне периодически нужно компилировать разные рантаймы: mono, coreclr, corert, крутить виртуалки и т.п. Для этого мне нужен полноценный топовый процессор, а не порезанное по TPD недоразумение, и, конечно же, быстрый SSD.

— То есть если ты хочешь работать над кодом Mono, тебе нужен нормальный комп?

— Mono включает в себя исходники .NET и .NET Core в виде сабмодулей, поэтому в итоге там огромное количество файлов, по которым надо как-то быстро перемещаться, поэтому самое главное — это быстрый SSD. Надо брать что-нибудь, начиная от Samsung 960 Pro и выше. Bottleneck всегда в IO.

— Опиши свой рабочий день

— Я работаю удалённо из Минска. Основная часть моей команды находится в США, хотя есть несколько человек в Европе, есть люди в Японии, Австралии, даже в Африке. Такая распределенная команда. Общаемся в основном в Slack, пару раз в неделю проводим митинги. Периодически встречаемся в Бостоне или Редмонде.

Задачи в основном довольно абстрактные. К примеру, портировать типы из определенного namespace. Я могу параллельно что-то брать, заходить на GitHub и фиксить какие-то баги. Периодически делаю что-то для .NET Core — пытаюсь что-нибудь оптимизировать или почистить.

— А откуда берутся задачи, как это организовано? Какой-то бесконечный Backlog?

— Задачи заводят пользователи и тим лиды, раз в месяц у нас есть неделя багфиксинга: целую неделю занимаешься только багфиксингом, другие дела бросаешь.

В остальное время также желательно не забывать про баги, но нужно придерживаться основных целей, к примеру моя цель — портировать основные типы из mscorlib и сделать Mono/Xamarin соответствующим NET Standard 2.1. Портирование типов обычно выглядит как выбрасывание старой реализации и заменой её ссылкой на код в .NET Core сабмодуль с адаптацией.

О Microsoft, осях и «предательстве»


— Ну да, лицензия позволяет. Да и вообще вы в одной компании.

— Да, позволяет. Мы и раньше так делали. Mono было частью некоторых дистрибутивов, по-моему, в Ubuntu и в GNOME даже было Mono. Мигелю говорили, что он всех под монастырь подведет.

— Да, я помню, его Столлман называл предателем.

— Боялись, что в любой момент могут нагрянуть адвокаты Microsoft и всех засудить, чего Microsoft, к счастью, так и не сделал.

— Ну да, Microsoft сделал прямо противоположное — стал Linux использовать у себя.

— Microsoft сейчас совершенно другой при новом СЕО, фокус на облачных технологиях привел нас в мир опенсорса и всего того, о чем раньше и подумать не могли. Сейчас возможно скачать Ubuntu WSL из Marketplace одним кликом, задеплоить MS SQL Server на Linux и разрабатывать под .NET из под macOS.

— То есть вы можете спокойно писать код под открытыми лицензиями и никто ничего не скажет?

— Да, конечно. Естественно, перед тем как выложить какой-нибудь внутренний проект в опенсорс нужна небольшая бюрократия, но в целом, я не встречал запретов на использование чего-либо.

— У тебя бывают задачи, которые требуют сразу трёх платформ?

— У меня целый набор: один компьютер на Windows, MacBook с macOS и ноутбук с Fedora. Также целая россыпь виртуалок, включая WSL. Чаще всего баги делятся на два типа — Windows и не-Windows, которые воспроизводятся как на macOS так и Linux.

Разбираемся с .NET Core и Mono


— Какие есть направления, которые тебе нравятся, и их можно развивать в .NET Core и в Mono?

— Лично мне нравится большой упор на производительность и кроссплатформенность. Производительно постоянно улучшается в боевых условиях начиная от Bing и заканчивая публичными бенчмарками типа TechEmpower, в которых .NET Core показывает себя с очень хорошей стороны наравне с решениями на базе Go, Java и С++. У многих людей до сих пор есть стереотип о .NET, как Windows-only технологии с тормозной виртуальной машиной — с этим стереотипом мы и успешном боремся.
Наша команда большое внимание уделяет АОТ сценариям и использованию LLVM в качестве бэкенда для генерации машинного кода. LLVM — очень мощный инструмент с огромным количеством оптимизаций. Нужно лишь аккуратно сгенирировать LLVM IR с минимальным количеством safe-points, чтобы не мешать этим самым оптимизациям. Лично я не так давно даже написал свой простой LLVM transformation pass.

Также радует, что C# и .NET являются мейнстримом наравне с С++ в геймдеве благодаря Unity и некоторым другим движкам, которые имеют C# скриптинг.
Есть потенциально интересное направление — компиляция C# в Web Assembly для браузера.

— Не знаю, как в .NET, но порой приходится тащить кучу стандартных библиотек для компиляции. В Java ты запускаешь Hello World, а у тебя грузится 2 тысячи классов. В браузере будет грузиться нехилое количество мегабайт. Что ты по этому поводу думаешь?

— Минимальный размер рантайма Mono с базовой библиотекой что-то около двух мегабайт. Но это проблема есть даже у Apple: приложения, написанные на Swift тащат каждое свой рантайм. Пока технология Mono-wasm сыровата и базируется на рантайме, который был АОТ скомпилирован в WASM + интерпретатор для пользовательского кода. Кстати, рантайм сейчас вот переписываем с С на С++, надеюсь, это не повлияет на размер в итоге.

— А вы не пробовали переписать Mono на C# вместо плюсов или C?

— Идея звучит неплохо, но потребовала бы просто нереальных ресурсов и у нас есть некоторые подвижки в этом. Команда .NET Core дошла до такого уровня C# и .NET, что плюсовый код заменяется на C#, чтобы не париться с кроссплатформенностью и при этом производительности он не теряет. Недавний пример — перевод реализации парсинга и конвертирования числовых типов и весь Decimal были переписаны на C#. Меня это очень радует и сильно упрощает работу по миграции кода.

О Garbage Collector


— Я видел .NET Core GC, которым пугают детей, потому что это полтора мегабайта исходника на C++! Полтора мегабайта, Карл! Вот это сколько книг?!

— Да-да, при этом в этом файле отметилось 47 контрибьюторов согласно гитхабу. Я не специалист по Garbage Collector, но вообще GC имеет под собой довольно общую теорию типа алгоритма Mark-n-Sweep, который усложняется поколениями и попытками максимально избежать полных остановок мира и делать всё параллельно основному потоку выполнения.

— У вас есть плагины или возможность менять Garbage Collector или он один?

— В Mono есть несколько реализации, а в .NET Core не так давно сделали публичный API, которые позволяет взять пару хедеров, написать свой ГЦ и подключить его в любое приложение одной переменной среды. В качестве примера есть статья о том, как написать ZeroGC для .NET Core. В мире контейнеров, где не обязательно убирать за собой мусор может быть актуально. В целом это позволяет кому-нибудь, к примеру, взять текущую реализацию и максимально оптимизировать ее для, допустим, геймдева, чтобы остановка мира и пробежка по всем объектам не лихорадила FPS к примеру или оптимизировать потребление памяти, по-моему ребята из Samsung так сделали для Tizen пару модификаций в GC.

— То, что Microsoft отпустил тотальный контроль над всем — это хорошо, ведь GC и JIT — это очень хороший инструмент контроля.

— Да. Посмотри на .NET Foundation — это ведь уже не только Microsoft. Там Google, Red Hat, Samsung, Intel, в общем, все компании, которые раньше, казалось бы, рядом с Microsoft стоять не будут. Разве что Apple не хватает.

О поддержке IDE


— Насчет IDE: насколько хороша в тулинге, в самом и в компиляторе в поддержке IDE? Сейчас есть всякие штуки типа Swift, где компилятор даёт очень мало возможностей поинтраспектить внутреннюю структуру, покешировать, ещё что-то. И это бесконечная боль, потому что тебе, когда делаешь какой-то свой тулинг, надо заново переизобретать весь мир. Насколько хорошо с этим в Mono? У вас своя IDE?

— Компилятор C# Roslyn изначально писался как не только компилятор C# в IL, но и бэкенд IDE и анализатор, он умеет переваривать даже плохой код. Ты можешь на основе его output просто показывать какие-то вьюшки и что-то делать, а он будет прямо говорить: «Покажи там менюшку», «предложи рефакторинг», «вот тебе превью изменений» и т.п…«выдели, вот такой рефакторинг и предложи юзеру». То есть этот компилятор прямо позволяет тебе быстро сделать свою IDE.

По сути, ты просто реализуешь набор интерфейсов для своего GUI, а у тебя уже есть IDE, которое поддерживает большой набор рефакторингов и тому подобное.

В целом, многие современные языки позволяют получить AST — абстрактное дерево выражений кода. Например, Clang отлично позволяет из плюсового кода получить абстрактное дерево, мы, кстати, используем эту особенность для генерации C# байндингов к С++ и Objective C коду.

— Ты пробовал использовать Visual Studio Code для чего-нибудь?

— Ну я бы сказал, что это самый основной мой инструмент.

— Допустим, чувак хочет открыть репозиторий Mono и похачить его. Что ему для этого нужно?

— На Windows просто открыть cолюшн рантайма и солюшн бцл и сбилдить оба. Благодаря эффективной параллелизации msbuild должен справится минут за 5. На macOS и Linux используется привычный подход через Makefiles.

О подготовке докладов и немного спойлеров


— Ты же с докладом приезжаешь на DotNext, а про что он будет?

— Мой доклад будет состоять из набора интересных примеров микрооптимизаций, примененных в самом .NET Core разработчиками и сторонними контрибьютерами, которые, мне кажется, могут быть полезны и прикладным программистам. Также уделю внимание неудачным примерам что-то заоптимизировать, к примеру, когда контрибьюторы хотят оптимизировать какой-то конкретный случай, но выходит это боком в виде регрессии в других. Отдельно будет десяток слайдов по новоиспеченному API к SIMD.

Ребята из Intel вместе с Microsoft-ребятами вывели наружу в C# низкоуровневое API для SIMD, который позволяет писать сверхбыстрые алгоритмы не полагаясь на компилятор, который, как многие думают, сможет сам всё что нужно оптимизировать и векторизовать — так не бывает.

— В общем случае это теоретически невозможно.

— Да, нигде не уйти от самостоятельной вставки интринсиков. Сомневаюсь, что в каком-либо языке можно описать перемножение или транспонирование матриц на простых типах и ждать от компилятора максимально эффективные SSE/AVX инструкции на выходе. Кстати, я уже применил эти C# интринсики внутри .NET Core для оптимизации System.Numerics.Matrix при помощи SSE и оптимизировал функцию GetHexDigits при помощи Lzcnt. Можно использовать как пример использования API в своих проектах.

— Когда приходят люди, которые разрабатывают что-то core-ное, ещё приходят те, кому интересно тоже в этом поучаствовать. Есть ли какой-то путь новичка?
Любой first time contributor получает большое внимание и помощь, многие простые задачи или баги, которые не требуют объемных знаний и высокого приоритетах могут помечаться специальным лейблом на GitHub — «up-for-grabs», либо «good first issue».

— Можно зайти на репозиторий, найти по этим меткам issues и выбрать близкий по духу. Например, довольно много задач о покрытии тестами каких-то кусков кода. Увеличение coverage тестами, — это вот прямо идеальная первая задача. Также хороший способ — это что-то побенчмаркать, сравнить с другими рантаймами и попытаться разобраться почему тот или иной код работает медленнее чем в .NET 4.x, к примеру string.GetHashCode. По бенчмаркингу есть большое количество выступлений и блогпостов от Андрея Акиньшина и Адама Ситника про очень удобный инструмент — BenchmarkDotNet, который простым движением руки — одним атрибутом покажет вам скорость выполнения кода, сравнит с другими рантаймами, расскажет за память и покажет ассемблерный код.

Т.е. минимальный набор действий — это просматривать все пулл-реквесты и задачи, подписаться в твиттере на таких людей как Matt Waren и Ben Adams, зайти в каналы corefx и coreclr в гиттере ну и прочитать документацию по BenchmarkDotNet.

— Да. Я вот сейчас отфильтровал тегу up-for-grabs, здесь около 600 issues, некоторые вообще без комментариев и их можно брать.

— Да, всё так. Ещё недавно проводили хакатон для .NET Core-команды. Выделили пару десятков issues-ов, и за день их нужно было пофиксить и получить за это приз.

— Это отлично. Рассказал много интересного, теперь хочу попробовать сам какую-нибудь issue зарезолвить. Правда, я не знаю C#, вот в чем проблема.

— C#, как мне хочется верить, довольно предсказуемый язык не смотря на больше количество сахара и обладая опытом в Java или С++, думаю, можно довольно быстро начать даже что-то оптимизировать в рантайме, опыт в других языках в этом даже поможет посмотреть на вещи с другой стороны.

— Я сейчас смотрю на репозиторий .NET Core и он выглядит очень прилично. И люди действительно общаются в комментах, прямо дискуссии проходят.

— Да, довольно активные. Там их и 100, и 200 комментариев. А учиться можно по базовой библиотеке классов, там довольно много интересных задач, которые может взять любой человек.

— Спасибо тебе большое за ответы! Встретимся на DotNext.

В этот раз минутка рекламы будет необычной, потому что пока мы готовили интервью, билеты на конференцию кончились. Хотите посмотреть доклады и не успели купить билет? Онлайн-трансляция все еще доступна на сайте.

Если у вас есть вопросы или невероятное желание посетить DotNext 2018 Moscow лично, напишите нам на tickets@dotnext.ru (возможно, кто-то вернет билет, и мы сможем вам помочь).

© Habrahabr.ru