Несколько недель назад я перешёл со среды разработки на Windows к другой на Linux. Я сделал это с проектом, который до того разрабатывался исключительно под Windows. В этом постинге я хочу описать проблемы, которые заставили меня пойти на такой шаг, небольшое описание самого процесса перехода и немного наблюдений о Linux для разработчиков.
Предыстория
Проект, над которым я работаю, написан на C++ с использованием небольшого числа утилит на Python. В начале я работал в Visual Studio 2005 на Windows XP. Это уже стало само по себе проблемой – обновление Visual Studio или системы не является тривиальной задачей, так как и ОС и среда разработки требуют покупки новых лицензий, а особенно в офисной работе новые версии покупаются не так уж и часто.
Эта проблема встала особенно остро, когда я начал распараллеливать части своего приложения. В своем ядре программа выполняет большие объемы численных вычислений, которые могут быть независимо обработаны в множестве маленьких блоков кода. Так как я не мог использовать OpenMP (сторонняя библиотека не могла быть слинкована, если задействован OpenMP), я управлял потоками вручную. К сожалению приложению требовалось выделение небольшого объема памяти для каждого потока, и как оказалось, такое масштабирование на XP выполнялась просто катастрофически. В то время как я получал прирост производительности при переходе от одного ядра к трём, всё явно замедлялось при задействовании четвертого ядра. Я столкнулся с проблемами либо диспетчера потоков, либо подсистемы управления памятью, так в моём коде вообще не было ввода-вывода.
Просто попробовав запустить это же приложение на Windows Vista, я обнаружил, что там оно более чем в два раза быстрее. Но, к сожалению, я не мог установить свою Studio на эту ОС – вопрос о разработке на XP и тестировании на Vista даже не стоял. Опять таки, с бесплатной средой, проблем бы не возникло, если бы… (express edition не имеет поддержки ни x64, ни OpenMP – смотри дополнение в конце!).
С другой стороны достать новый Linux с новым компилятором не составляло для меня никакой проблемы. При помощи Wubi можно запустить Linux на том же компьютере, где стоит Windows даже без переразбивки жесткого диска. Это особенно удобно в корпоративном окружении, где нельзя просто удалить раздел и установить на него Linux, не вызвав праведного гнева администратора.
Linux
Я использовал Wubi и установил с его помощью Kubuntu,так какKDE мне нравится больше – особенно потому что сейчас я использую Qt для разработки интерфейса с пользователем. То есть я использовал Kubuntu 9.04 x64, до этого я пользовался x86 Windows XP.
Портирование
Я начал с загрузки кода из SVN, и, естественно, с этим не возникло никаких проблем. Но, хотя приложение и было написано на стандартном C++ и не полагалось на специфические для Windows вызовы, оно было сохранено в проектных файлах Visual Studio и использовало несколько вызовов WinAPI. Первым делом я перенёс все на CMake – в принципе это следовало сделать еще находясь на Windows. При помощи CMake, я смог быстро конвертировать один подпроект за другим и сразу же проверить из на наличие ошибок компиляции. Этот путь хорошо себя зарекомендовал – я ни разу не оказывался в ситуации, когда бы я получал множество ошибок компилятора или линковщика сразу. Такая ситуация возникала у меня, когда я переводил проект уже на CMake с Windows на Linux и попробовал сделать всё одним махом. Во время переноса лучше двигаться поступательно от одного подпроекта к другому, даже если весь проект использует изначально портируемую систему.
Как я уже говорил, на Windows я использовал явное управление потоками, которое я заменил на OpenMP на Linux. Теперь я мог выбросить и множество конфигурационного кода для потоков, например мне не надо было понижать приоритет своего приложения, чтобы оно просто не зависло, как это было на XP. Конечно, можно было использовать и Boost.Threads, но OpenMP хорошо работает с циклическим параллелизмом, который использовал я, и общая модель даже упростилась по сравнению с той, которую я создал полностью сам.
Для графики я уже использовал OpenGL. Так у меня без проблем получилось запустить бинарные драйвера от nVidia, то и с этим не возникло никаких проблем. В общей сложности портирование заняло у меня полдня, включая время на установку и настройку Linux.
Результаты
Общие результаты весьма интересны: то же самое приложение теперь работает в 5-10 раз быстрее, используя все четыре ядра, то есть перенос на Linux определённо того стоил. Я думаю, что с Visual Studio 2010 на Windows 7 я получил бы такую же производительность, но ключевой момент здесь в том, что заставить работать ваш код на Linux не стоит вам ничего кроме времени, и очень немного, если делать это аккуратно. Использование CMake (или другой портируемой системы сборки), написание более или менее чистого C++ и использование портированных библиотек делают перенос на Linux осуществимым без особых проблем, а сам переход на другую систему несложен. В настоящий момент, средства разработчика на Linux вполне удобны и “болезненного перехода” от Visual Studio на, к примеру, KDevelop или Eclipse CDT больше нет.
На самом деле, переход настолько прост, что фирме Microsoft стоит серьёзно задуматься. Например, я последние несколько лет писал код исключительно под Windows, и только время от времени пробовал Linux, но никогда не переключался на него полностью из тех или иных больших или маленьких проблем. И вот, в последние год или два, Linux-desktop, вместе со всеми программами, доступными на нём, может предоставить некоторые реальные преимущества перед Windows, особенно если у вас нет доступа к самым последним продуктам от Microsoft. До недавнего времени последние предоставляли самые лучшие средства разработки и стабильные API, что, на мой взгляд, и являлось краеугольным камнем их успеха. Теперь же, они меняют интерфейсы достаточно быстро (WinForms? WPF? WinAPI?), они создают платформы, которые требуют полного переписывания существующего кода (Я всё еще жду приложение, подобного AutoCAD, которое бы состояло из интерфейса на C# и бэкэнда на C++), да и цикл выпуска новых приложений просто слишком долгий – ждать два года, чтобы получить исправление компилятора, просто смешно.
С другой стороны, разработка на Linux означает, что у вас есть очень стабильный API (например, POSIX не собираются заменять на PoseFX), создание интерфейсов просто и понятно (на выбор GTK или Qt), и средства разработки движутся вперёд семимильными шагами (GCC и LLVM становятся день ото дня краше, и установка нового компилятора не требует покупки еще одной лицензии). Если Microsoft не одумается со своей политикой продажи Visual Studio 2010 и не даст четких и ясных ответов на вопросы о своём API, я думаю, всё больше разработчиков найдут, что Linux может быть замечательной средой для создания приложений.
[Добавление] Надо что-то сказать в связи с тем, что эта статья привлекла большое внимание и многие понимают её несколько неправильно. Относительно библиотеки – у меня был доступ к исходному коду, я мог собрать её на Windows – это просто заняло бы очень и очень много времени, так как она зависит от множества библиотек, как например zlib, которые мне бы тоже пришлось собирать с новыми настройками на Windows. Используя Linux удовлетворить все эти зависимости гораздо легче.
OpenMP против ручного управления потоками: производительность по сравнению с явным управлением многопоточностью не улучшилась, но это дало очень милый бонус в виде более чистого кода. На Windows я не мог использовать OpenMP в связи с проблемами линковки. Еще один бонус получился от перехода с x86 на x64. И наконец, управление памятью в Linux гораздо лучше для многопоточных приложений, и из этого получился самый большой прирост производительности. В целом, приложение работает в несколько раз быстрее, без изменений с моей стороны.
Итог: В данном конкретном случае, переход на Linux занял у меня всего несколько часов, в то время как результат того стоил: улучшение производительности, меньше мороки с зависимостями. Минусы – надо привыкнуть к Linux и другим средствам разработки – для меня полностью перекрываются плюсами. Это главная мысль этого поста. Я был поражён насколько легко было полностью перевести этот проект с Windows на Linux, так как я ожидал массу проблем (например, вообще невозможность запустить хоть что-нибудь из проекта!).
Всё могло бы быть по-другому, если бы на Windows было бы проще собрать все библиотеки и зависимости, и у меня бы был доступ к новому компилятору, но всё получилось, как получилось, и я совершенно не скучаю по Windows у себя на работе.
[Добавление 2] x64 версия Visual C++ Express требует некоторой настройки, чтобы поддерживать x64, но это возможно, если вручную добавить компиляторы из Windows SDK. Можно обратить к официальной документации или одному из пособий, как это сделать.