суббота, 7 марта 2015 г.

Пару слов о конференции C++ Russia 27-28 февраля 2015

Вступление

Я посетил конференцию http://meetingcpp.ru/, данная конференция посвящена языку C++ и проводится регулярно в России. Итак, ниже мои впечатления о конференции. Я разделил доклады на несколько основных направлений, хотя на самой конференции такого деления и не проводилось.

Многопоточность и асинхронность

Данное направление было представлена довольно обширным количеством докладов – тема востребована и актуальна для C++ сообщества. На самом деле, докладов в это направлении было больше, но я также хотел послушать доклады с других секций.


  • Sean Parent – его доклад был посвящен многопоточности, в частности он рассказывал, как они добивались максимальной производительности для рендеринга изображений, в т.ч. внутри браузера. Также были подробно разобраны основные проблемы дизайна подисистеы многопоточности в C++. В частности, он подробно рассматривал std::future и то каких операций не хватает для программистов. Больше информации можно найти здесь. Сам доклад был довольно сложен, и длился 2 часа, поэтому после полутора часов я потерял нить рассуждений и практически полностью пропустил одну из тем доклада.
  • Rainer Grimm – его доклад был посвящен прикладным проблемам многопоточности. Начали с простых проблем – дедлоки, race conditions, позже перешли к проблемам, возникающим при неправильном использовании std::atomic – в частности, неправильном выборе типов доступа к памяти (acquire/release, relaxed и пр). Также были показаны две основные проблемы с std::conditional_variable – spurious wakeup и lost wakeup, если первую еще можно решить, введением дополнительного флага, то вторая проблема – концептуальна. Она возникает, если один потоков пытается сигнализировать на contional_variable, в то время как на ней может никто не ждать. Также был продемонстрирован пример использования std::future совместно с std::promise для решения проблемы с lost wakeup. Доклад был довольно простой, но докладчик сделал его интерактивным, поэтому слушать было интересно. Вердикт – лучше использовать std::fututre + std::promise вместо низкоуровневых std::mutex + std::conditional_variable там где это можно.
  • Ivan Cukic – его доклад был посвящен асинхронному программированию с небольшим уклоном в функциональное программирование. Докладчик продемонстрировал основные проблемы при написании асинхронного кода – разорванность контекста при асинхронных операциях, что существенно затрудняет отладку и анализ кода. Для решения этой проблемы был предложен механизм, который позволяет писать асинхронные программы в императивном стиле – были добавлены специальные операции if_(…), else_(…), for_(…) и т.д. Данный подход позволяет писать в привычном стиле. Кроме того, данный подход облегчает тестирование кода - такой код автоматически становится синхронным (все зависит от способа получения входных данных), если механизм получения данных асинхронный, то код работает асинхронно, если получение данных синхронно – то код работает синхронно. Доклад средней сложности, необходимо понимание std::range из еще невышедшего C++17, также принципы работы некоторых асинхронных библиотек (например, boost::asio), std::future.

Generic (meta)programming

В данную секцию я выделил доклады, которые затрагивают вопросы дизайна и парадигм программирования на языке C++ (в том числе и template programming)


  • Bartosz Milewski – его доклад рассказывал о теории категорий для C++ программистов, также был приведен пример реализации чистых функций на языке C++ для случая, когда требуется трассировка внутри функций. В примере с трассировкой был показан способ как сделать функцию чистой, а также добиться композиции таких функций – необходимо саму трассировку отложить до того момента, когда она реально понадобится – например, в  случае возникновения ошибки. В самой же реализации функции достаточно расширить тип возвращаемого значения, чтобы вместе с результатом выполнения возвращать и данные для трассировки. Была также показана связь данного подхода с концепцией std::future. Сам доклад был довольно простой, в основном, благодаря самому докладчику. Единственное, вызывает некоторые опасения оторванность от реального мира.
  • Zoltan Porkolab – докладчик рассказал об их патче для clang, который позволяет собирать статистику и трассировку процесса инстанциации шаблонов. В частности, данный механизм позволяет анализировать время инстанциации, затраченное количество памяти самим компилятором. Также можно анализировать процесс инстанциации с целью понимания, почему, например, при SFINAE были выбраны те или иные типы. Данное расширение сам автор позиционирует как инструмент для разработчкиков компиляторов. Доклад довольно простой, докладчик говорил с тяжелым славянским акцентом на английском языке, так что понимать докладчика было довольно легко.
  • Guntram Berti – доклад был посвящен проблемам дизайна и производительности стандартной библиотеки. Автор предложил простую функцию sum, которая суммирует последовательность данных. На примере этой функции были показаны проблемы с концепцией итераторов в C++, был предложен обходной вариант (Более подробно об этом можно прочитать у Эрика Ниблера). Затем была рассмотрена проблема плохой производительности std::deque по сравнению с std::vector при суммировании элементов с помощью функции sum (а также, с помощью любого std алгоритма), было предложено ввести еще одну категорию итераторов, с помощью данной категории можно добиться существенного увеличения производительности (у автора получилось сократить время отставания с 4x до 1.6x). Доклад средней сложности, желательно понимание std::range из C++17, также рекомендуется почитать Эрика Ниблера (ссылка выше). Сам доклад хорошо структурирован и докладчик очень хорошо и доступно объясняет, хотя меня вначале испугало большое количество слайдов (80).

Прочие доклады

Сюда попали доклады, которые не попадали под мои категории, но тем не менее это не умаляет их важности и интересности.


  • Сергей Анпилов, Виктор Петров – практика использования Dependency Injection. Доклад от нашей продуктовой команды, был посвящен проблемам, встречающимся при использовании паттерна Service Locator – в частности, неочевидном списке зависимостей для компонент. Был рассмотрен паттерн Dependency Injection, также рассмотрены несколько библиотек, которые предоставляют возсожности для DI. Докладчики сформулировали список требования к DI фреймворкам, и в конечном итоге приходят к выводу, что ни один из фреймворков их не удовлетворяет, в результате они остановились на своем решении. Доклад очень простой – можно считать как обзорный.
  • Дмитрий Вьюков – доклад о Address/Memory/Thread Sanitizers – тулзы, которые встроены в компиляторы gcc и clang. Данные тулзы позволяет инструментировать код программы в процессе компиляции, и в процессе выполнения отслеживать и диагностировать различные проблемы – выход за границы массивов, использование неицилизированных переменных, а также проблемм с многопоточностью. В докладе были представлены технические подробности реализации таких тулзов. Также были представлены преимущества данного подхода по сравнение с неинвазивными анализаторами (valgrind) – это существенный выигрыш по производительности (в десятки раз), а также наличие новых возможностей, которые в принципе нельзя реализовать в valgrind. Также было отмечено, что данный подход не зависит от оптимизаций, и можно использовать и в Release билдах. Поддержка платформы Windows в планах. Доклад довольно простой, в основном, благодаря докладчику. Сам доклад довольно интересен с технической точки зрения (в плане реализации таких тулзов).
  • Игорь Гусаров – доклад об оптимизации трассирования. Доклад от эксперта нашей Лаборатории Касперского о проблеме производительности, которую они решали, и как эта проблема производительности привела к трассировке. Проблема производительности заключалась в том, что при выход из гибернации с установленным продуком был очень медленный, проблема заключалась в том, что бинарный код содержал очень много inline подстановок от механизма трассировки (как автор сам назвал его – код очень рыхлый). Поэтому полезная нагрузка была размазана по коду, из-за этого возникали частые page fault при восстановлении из гибернации, что существенно замедляло процесс запуска. Было разработан механизм, который позволяет избавиться от inline подстановок при вызове трассировки, с сохранением стримового интерфейса логгирования. По сути код дизассемблера стал похож на код при вызове printf функции: push, push, push, … call. Данный подход, кроме всего прочего существенно упрощает дизассемблер функции с трассировкой. Кроме всего прочего стоить отметить, что данная реализация возможна с помощью стандарта C++98. Доклад средней сложности, в частности, я не совсем понял механизм избавления от инстанциации операторов вывода в стрим (наверное, вечер второго дня – сказывалась усталость). При этом стоит отметить, что благодаря, докладчику сложность доклада была приемлемой (и не стала сложной).
  • Антон Полухин – доклад активного контрибьютора Boost. Докладчик рассказывал о процессе разработки библиотек Boost, а также о процессе принятия библиотеки в семейство Boost. Сам доклад не содержал технических подробностей и был обзорным.
  • Неизвестный автор – промо доклад от компании IncrediBuild. Обзор и реклама продуктов для ускорения процесса сборки Visual Studio проектов. Стоит отметить низкую степень подготовки доклада, хотя были и объективные причины – народ начинал расходиться и в зале было довольно шумно.

Выводы по официальной части

 В целом доклад очень понравился, стоит отметить высокое качество организации конференции, хотя в зале "А" были небольшие проблемы с освещением. Выражаю огромную признательность Сергею Платонову - организатору конференции! Также был приобретен крайне полезный опыт - мой TOP 3 полезных докладов – Игорь Гусаров, Guntram Berti, Дмитрий Вьюков – доклады от данных докладчиков довольно тесно пересекаются с нашей спецификой. Также на неофициальной части было выпито огромное количество пива - я за два дня в сумме выпил около 15 бокалов пива:). Также спасибо Bartosz Milewski за итальянское вино и лимончеллу - хотя наутро я сожалел о своем решении попробовать их :).

Считаю, что конференция удалась, и была крайне полезной для меня.

четверг, 1 января 2015 г.

Парад планет

В фильме «2012» парад планет 
оказывает негативное влияние на Солнце,
 что приводит к ужасным катаклизмам на нашей планете.
 (выдержка из Wikipedia)

Был на работе недавно довольно эпичный баг. Сформулирован он был примерно следующим образом: после развертывания компоненты FDE (Full disk encryption) Windows загружается но на экране ничего не отображается (черный экран). Разбирательство с этим багом у нас заняло несколько месяцев (естественно, не фулл-тайм), и вот, наконец, мы докопались до сути.

Итак, в этом баге встретились несколько особенностей: во-первых, особенности реализации  эмулятора 16-ти битного кода в ядре Windows, во-вторых, особенности BIOS конкретной машины, ну и в-третьих, наша пребутовая компонента, которая перехватывает некоторые прерывания BIOS для своих нужд.

пятница, 13 июля 2012 г.

Восхождение на белуху. Первый блин комом.

Хотя блог и тематический, решил написать сообщение не по теме, ибо слишком много эмоций и переживаний (положительных) подарил мне этот поход.

суббота, 21 января 2012 г.

Secure Coding

Наша компания купила курс для программистов C, C++: "Secure Coding in C and C++". Для проведения курса был приглашен преподаватель из Carnegie Mellon University. Я попытаюсь сделать краткий обзор лекций, которые нам были прочитаны. Скажу сразу - это мое субъективное мнение.

воскресенье, 25 декабря 2011 г.

И снова про синтаксические особенности C++

В C++ очень сложный и неоднозначный синтаксис (гораздо сложнее, чем в том же C). На эту тему было написано немало статей, книг. Ниже я приведу несколько особенностей, на которые я натолкнулся недавно, причем, на некоторые я наступаю не в первый раз.

понедельник, 21 ноября 2011 г.

Что же такое type erasure?

В данном случае мне кажется, что проще привести пример, который обрисует проблему. Итак, предположим, нам необходим список, содержащий функции со следующей сигнатурой:
typedef int (* nullary_function_returning_int_t)();
_Winnie C++ Colorizer
Окей, скажем мы:
typedef std::list<nullary_function_returning_int_t> func_list_t;
_Winnie C++ Colorizer
Но, что если мы хотим хранить не только функции, но и объекты у которых есть оператор (), возвращающий int. В таком случае, мы могли бы сделать базовый класс:
class nullary_function_base { public:
 virtual ~nullary_function_base(){}

virtual int operator() () = 0; }; typedef std::list<nullary_function_base * > func_list_ptr_t;
_Winnie C++ Colorizer
Но в таком случае мы ограничены только теми объектами, которые являются наследниками класса nullary_function_base. Как быть с функторами, которые получаются, например, в результате использования std::bind1st и пр.? Ведь в этом случае мы уже не можем сделать его наследником nullary_function_base. Или если используется обобщенное программирование и тип функтора просто неизвестен (например, внутри шаблонного класса, функции)?
Вот как раз для решения такой проблемы и используется type erasure.

вторник, 8 ноября 2011 г.

std::auto_ptr vs boost::scoped_ptr vs std::unique_ptr

Что такое smart pointer я думаю известно, на всякий случай о них можно прочитать в Википедии. Существуют различные виды умных указателей, и каждый из них имеет свою область применения, но одно у них общее - они обеспечивают управление (в том или ином виде) сроком жизни сырого (raw) указателя.

В данном примере мы рассмотрим три вида smart pointer. Все они предоставляют практические одинаковые возможности по управлению raw pointer. Также мне бы хотелось разобраться почему в новом стандарте C++11 auto_ptr объявлен устаревшим, что нужно использовать вместо него, и какие возможности есть в компиляторах не поддерживающих новый стандарт.