Дмитpий Hecтepук

Блог о программировании — C#, F#, C++, архитектура, и многое другое

Posts Tagged ‘cplusplus

Воскрешение языка С++

23 комментария


Сдается мне, что на всей нашей круглой планете вряд ли можно найти человека, который мог бы с уверенностью сказать, в чем заключается стратегия Microsoft относительно разработки в целом. Жив ли WPF, что будет с Silverlight для веба, откуда такой ажиотаж вокруг HTML 5 и причем тут, наконец, С++? Иногда мне кажется что ни у кого нет ответов на эти вопросы, и что в погоне за добычей (добычей тут может быть, например, рынок планшетов), не возбраняется полностью смешать все карты и начать заново.

Тем не менее, мы должны признать, что по крайней мере в свете анонсов касательно WinRT, язык программирования С++ снова становится более актуальным чем ранее. Да и не только сам С++. Ведь фактически то, что нас ждет, это некая реинкарнация COM, правда с другими терминами и, возможно, меньшим количеством проблем. (Ведь неслучайно PIA – Primary Interop Assembly – расшифровывается также как Pain In the Ass;)

Если быть честно-откровенными, то тот С++ который предлагает нам Microsoft – это совсем не «стандартные» плюсы. Хотя, точно так же как и в случае с C++/CLI, остается возможность использования «труъ» кода, который был написан ранее. Но вот уже в 3й раз нам предлагают некую магию.

Почему в 3й? Ну, 1м разом я считаю все те изменения языка, которые не были стандартизованы. С Java/Visual J++ такое не прошло т.к. там правила ныне отошедшая на покой компания Sun, в случае же с С++ не нашлось стороны, которая единолично планировала бы получать доходы с этого языка. Поэтому Microsoft могла сделать все, что угодно – добавить поддержку свойств (да-да, свойств в стиле C#) с помощью __declspec(property), замутить поддержку COM с помощью #import, ну и так далее. Вторым вмешательством в С++ можно считать MC++ и с последствии С++/CLI, который добавил массу ненужных ключевых слов, а также эти ненавистные шляпки (^) для классов. Ну и так далее.

Впрочем, создание C++/CLI было вынужденным. Я это начал понимать только тогда, когда начал встречать кросс-платформенные (!) библиотеки на С++ которые компилировались, помимо обычного С++, еще и с «управляемой прослойкой» для .Net языков. Идея в принципе оказалась правильной – дать .Net разработчикам всю мощь С++ библиотек без особого напряжения в виде P/Invoke или надобности обращать С++ библиотеки в COM.

Ну и наконец, шаг 3й – это полностью узаконить любые новшества в С++ сделав его одним из официальных языков разработки для Windows. Это на самом деле лицемерие – ведь для Windows итак можно писать на «плюсах» используя MFC или даже WTL. Но уверен что мало кто этим занимается. Потери от этого больше, чем потери от требования наличия .Net Framework Client Profile на компьютере. Кстати – недавно в процессе тестирования лицезрел что происходит если поставить ClickOnce-программу которая использует .Net 4 на Windows XP. Инсталлятор сам скачивает и устанавливает framework. Это конечно нехилый download, но большинство людей 100-мегабайтные файлы уже практически не пугают.

Так вот, хотите вы этого или нет, С++ будет использоваться Microsoft в своих целях, связанных с разработкой под Windows. Но это конечно не значит что вы не сможете получить от этого бенефиты, даже если пишете на .Net.

Приемущества С++

Давайте определимся с тем, что же дает нам С++ чего не может дать тот же C#.

Ручное управление памятью. У меня в голове иногда случаются страшные баталии, связанные с тем, нужно ли делать объект структурой или классом. В принципе, в .Net нам пытаются навязать ограничение, связанное с размером объекта – дескать, если маленький то можно и структуру, а иначе ни-ни. Но это подразумевает что мы, разработчики, наивно делаем pass by value и тем самым поедаем память. Что не всегда так.

Доступ к высокопроизводительным инструкциям процессора. Возьмем например SIMD. Думаю можно с большой степенью уверенности сказать, что JIT-компилятор не оптимизирует и никогда не будет оптимизировать код под SIMD. Соответственно, мы с Microsoft.Net начинаем проигрывать даже Mono, где есть соответствующий пакет.

Прямой доступ к намного более зрелым и продуманным библиотекам. Это более сумеречный бенефит, т.к. API таких библиотек порой ужасно. Но надо смотреть не только на API но и на производительность.

О да, я же забыл упомянуть о самом важном – Microsoft ныне разрабатывает свои библиотеки для С++. Примером такой библиотеки может быть вышеупомянутая Parallel Patterns Library (PPL), которая с одной стороны может считаться «неуправляемым» аналогом .Net’ного TPL, а с другой – конкурентом Intel Threading Building Blocks (TBB). Но на этом все не останавливается – Microsoft работает еще на одной библиотекой под названием C++ Accelerated Massive Parallelism (AMP), которая будет заниматься поддержкой вычислений как на CPU так и на GPU.

Программирование для GPU заслуживает отдельную заметку. На данный момент, графические процессоры можно программировать с помощью OpenCL (вариации языка С++ для различных устройств), CUDA C (подобия С++ для чипов NVidia, кстати с прекрасным тулсетом для Visual Studio). Существуют также решения на .Net, такие как исследовательский проект Microsoft Accelerator (который, насколько я знаю, также работает с FPGA) или коммерческое решение GPU.NET.

Недостатки С++

С++ архаичен. Использовать его для ООП – делать себе плохо. Даже со всеми новшествами C++ 2011 является динозавром, пусть и динозавром который пока не думает вымирать. С другой стороны, С++ прекрасно подходит для производительных алгоритмов.

Приведу пример. Мне в TypograFix нужно обрабатывать Bitmap’ы. Если использовать .Net, то единственная возможность получить более-менее вменяемую скорость по обработке картинок – это использовать unsafe. Что как бы само по себе не очень эффективно, но даже если у вас получится, вы не сможете эффективно настроить параллелизацию unsafe кода. (Автор пробовал использовать TPL и unsafe, с весьма мутными результатами.)

Еще одна проблема – это нехватка инструментария. Отладчики конечно есть, но вот анализа кода в стиле Решарпера мне очень нехватает. А ведь это как раз тот «небезопасный» язык, в котором так нужны всяческие проверки, причем чем их больше, тем лучше.

Это основные недостатки, но есть и масса других. Скорость компиляции, неинформативность ошибок, итд, итп. Масса компромиссов, на которые можно пойти в погоне за производительностью.

AMP

У инициативы AMP есть одно существенное приемущество – над этой технологией работают AMD и NVidia, две компании которые держат рынок графических карт (лично я тяготею к AMD потому что у них есть Eyefinity). Работают они над ней, конечно, с Microsoft, т.к. у всех трех компаний есть уклон в сторону различных процессоров. Кстати, в случае с Microsoft, это конечно же ARM, о котором вы все уже наверняка наслышаны. Соответственно идея, как мне кажется, в том, чтобы иметь код (возможно даже код низкого уровня – драйвера, кодеки, и т.п.) который мог бы выжать максимум возможностей из любого процессора.

С другой стороны, по крайней мере для GPU, поддержка идет по наименьшему знаменателю, и этот знаменатель называется DirectCompute. Поэтому неизвестно, будет ли AMP настолько эффективен как например CUDA C или кросскомпиляция, скажем, C# в NVidia PTX (именно это делает GPU.NET). Также непонятно, придется ли писать fallback-код для CPU в случае отсутствия девайса с поддержкой DirectCompute – если это придется делать, то часть шарма данного подхода пропадет, т.к. это точно не «write once, run everywhere».

Intel C++

Microsoft не является единственной компанией, которая выпускает компилятор С++. Intel тоже делает компилятор, в большей степени заточенный на свои процессоры, с неплохой интеграцией в Visual Studio. Важен не только сам компилятор (а он хорош), но и тулсет – отладчик, профилировщик, библиотеки. Все это на высоте. Библиотеки, например, работают более резво на процессорах AMD чем библиотеки самой AMD.

На сегодняшний день я готов работать только с компилятором Intel. Я не использую C++/CLI, мне хватает P/Invoke. На самом деле, технология P/Invoke – настолько простая и понятная, что я не чувствую особого стеснения когда пишу часть проекта на C# а часть на С++. Что P/Invoke не поддерживает так это, конечно же, ООП и возможность передавать туда-сюда классы, но тут я скажу вот что: если вы используете С++ именно для ООП (или для взаимодействия с .Net) – вы делаете что-то не так. На С++ нужно писать производительные алгоритмы, или использовать уже существующие библиотеки (например, Intel TBB, MKL или IPP). Потреблять ООП-структуры там бесполезно, но с другой стороны, не возбраняется потреблять оттуда COM. Например, когда только вышли библиотеки Direct2D/DirectWrite, я захотел ими воспользоваться в WPF-проекте и просто написал C++ DLL’ку, которая рисовала в «залоченый» System.Drawing.Bitmap. Никаких проблем.

OpenMP

OpenMP – это поддержка декларативной параллелизации на С++. Это может показаться шуткой, но на самом деле это старая, проверенная временем технология, которая работает. Для большинства случаев data-level параллелизации в стиле parallel_for() подходит именно OpenMP. Я много где использую именно OpenMP, оставляя Intel TBB для более сложных задач, где автоматический подход не сработает.

Конечно, в .Net есть некий аналог – использование TPL и надежда на то, что JIT-компилятор магическим способом оптимизирует и «векторизует» сгенерированный код. Но это достаточно наивно. Пока вы проверяете индекс элемента доступа к массиву, вы теряете в производительности. Как только вы это отключите, у вас начнутся уже другие проблемы.

Если честно, я не большой фанат TPL. Для простеньких случаев в которые не хочется вникать, я просто пишу Parallel.Invoke или вставляю AsParallel() в цепочку LINQ-запроса и надеюсь на лучшее. Но если мне нужно почитать дистанцию Левенштейна на огромном наборе данных, то я даже напрягаться не буду – отошлю все данные в неуправляемый код, а там уж сделаю все «правильно».

Заключение

Я надеюсь, что повышенное внимание к С++ приведет к улучшению редактора. Правильный IntelliSense уже будет достижением. А что еще надо – ах да, возможно какой-нибудь генератор P/Invoke оберток и соответствующей документации для того чтобы упростить процесс.

К слову скажу, что недавно пытался найти нормальный блог по С++ путем вбивания “с++ блог” в гугле. Гугл выдал какой-то мусор. Если кто-то знает интересные блоги на русском, дайте ссылочку в комментариях. Спасибо.

Реклама

Written by Dmitri

30 октября 2011 at 0:13

Опубликовано в Programming

Tagged with