ПодКапотом

Некоторые аспекты работы "железа" и памяти.

Как правило всплески заинтересованностью аппаратной частью у меня возникают перед появлением или после появления в пользовании некоторого девайса.

Перед - естественно это решение вопросов выбора, после - как правило пустой интерес.

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

Итак, в основном здесь будут ссылки на понравившиеся статьи, с удивительно короткими комментариями, по сравнению с теми что я обычно до этого делал.
Читать далее...

Аллокаторы в C++. Или свой распределитель памяти.

"Allocator" - переводится как "распределитель" - попросту говоря аллокатор - это действующая по определённой логике высокоуровневая прослойка между запросами памяти под динамические объекты и стандартными сервисами выделения памяти (new/malloc или другими (например запросами напрямую к ядру о.с.)), конечно же прослойка берет на себя и вопросы управлением отдачей уже ненужной памяти назад. По другому можно сказать - что аллокатор это реализация стратегии управления памятью.

Использование аллокаторов позволяет добиться существенного повышения производительности в работе с динамическими объектами (особенно с объектами-контейнерами). Если в коде много работы по созданию/уничтожению динамических объектов, и нет никакой стратегии управления памятью, а только использование стандартных сервисов new/malloc - то весьма вероятно, что не смотря на то, что программа написанна на Си++ (или даже чистом Си) - она окажется более медленной чем схожая программа написанная на Java или C#.
Читать далее...

Посравниваем несравнимое? ) или немного метапрограммирования

Первая заметка за жизнь в этом блоге, но в ней будет и полезное про программирование)

Недавно довелось быть приглашенным в очень интересный проект, спасибо одному форму. Не знал что такое работает - просто написал мол "изучаю ++, буду рад принять участие в любом проекте на этом языке". Писал даже без надежды, просто так.. В итоге совершенно не ожидал что после этого:

  1. Действительно можно быть приглашенным в проект.
  2. Проект окажется не херней типа собрались джуны писать примитивную игрушку*/мессенджер/шифратор и т.п... (т.е. не бессмысленным, а вполне себе и технологически качающим скилл, и более того имеющим шанс по завершению на монетизацию, или по крайней мере на востребованность в рамках free software).
  3. То что буду приглашен не в один проект, при том новые приглашения будут не в менее крутые проекты, даже такие, которые уже приносят монеты их авторам**.

* - впрочем буду крайне рад присоединиться к любому геймдев Си++ проекту, любой сложности, а в скоре, как будет свободнее со временем буду уделять время разработке своих собственных игрушек, идеи есть еще с прошлой зимы, но пока не довелось...
**, хех, помню что кто-то говорил фриланс на Си и Си++ - миф. Не миф, но найти такой фриланс редок, очень.
Читать далее...

Почему в Си++ нужно использовать nullptr а не 0 или тем более не NULL

Начну рассказ с Си. Не секрет, что указатель, с которым ведется работа, всегда должен быть проинициализирован. Т.е. он должен или на что-то указывать (на реально существующий объект в памяти) или же быть нулевым. Это защищает от потенциальных проблем связанных с возможностью разыменования указателя, который не указывает ни на что (вообще разыменование такого указателя - это Undefined Behavior, но жизнь складывается так что это
Читать далее...

Тайны std::declval, или как "обманывать" компилятор

Это не самостоятельная статья, а инкапсуляция этой статьи.

На самом деле никакого обмана нет, это специальное допущение, оставленное разработчиками компилятора, для возможности обращаться к типам.

Возьмем немного измененный пример из описания самой std::declval - http://en.cppreference.com/w/cpp/utility/declval. Есть два класса, один с конструктором по-умолчанию, и один без такого конструктора:
Читать далее...

Метапрограммирование. Часть 2. Продвинутый уровень.

Базовые типы

В мире метапрограммирования 11-го стандарта "под капотом" все несколько сложнее, взамен простому объявлению __is_integer добавлен шаблон std::is_integral, А взамен объявления пустых структур, как типов истинности, появляется базовый класс std::integral_constant, содержащий несколько больше данных внутри себя, а соответственно и возможностей применения. Например - оператор преобразования к типу. И уже на базе него строятся типы истинности, хотя в общем идея абсолютно та же.
Читать далее...

Метапрограммирование. Часть 1. Взгляд издалека.

Метапрограмма - программа порождающая программы. Понятие обширное, и более широкое чем поддержка метапрограммирования языками программирования (которые в той или иной степени поддерживают парадигму метапрограммирования).

Примером метапрограммирования в Си++ являются шаблоны. Ведь шаблоны фактически это описание правил, по которым, в момент компиляции, будут созданы уже настоящие функции.
Читать далее...

STL. Алгоритмы.

Продолжаю вхождение в STL. Вот добрался и до "алгоритмов" :)
Конечно, некоторые из них уже успел попользовать давно, но не полностью осмысленно. А это не так интересно, как залезть внутрь.

Итак, поехали) <эта запись будет справочником по алгоритмам, которые привлекут моё внимание, и будет постепенно пополняться>

Введение

Алгоритмами в STL называются функции, для работы с последовательностями. Каждый алгоритм является шаблоном или набором шаблонов (перегрузка).

Последовательность в любой алгоритм передаётся в виде полуинтеравала [first, last), который указывает на первый и "следующий за последним" (приблизительно говоря мнимый элемент, указывающий на границу последовательности) элементы последовательности.
Читать далее...

Базовые классы функциональных объектов STL

Как писал тут, по STL можно учиться хорошему проектированию иерархии и интерфейсов. То есть тому как можно делать. Но и даже в таком мощном средстве как STL можно найти то, на чём можно поучиться как делать не стоит. (об этом в самом низу, а так эта статейка полна восхищения ^_^)

Как говорилось в той статейке про итераторы (приведённой выше по ссылке), поскольку в "алгоритмах" итератор является представителем объекта контейнера, ему необходимо не только уметь разадресовываться и указывать на следеющий/предыдущий элемент контейнера, но так же предоставлять и всю необходимую информацию о контейнере (вернее о его элементах). Например алгоритму копирования ничего не нужно знать о типах элементов

  1. template<class InputIterator, class OutputIterator>
  2. OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
  3. {
  4. while (first!=last) {
  5. *result = *first;
  6. ++result; ++first;
  7. }
  8. return result;
  9. }

Читать далее...

немного про архитектуру STL итераторов

Рассматривая STL можно увидеть как элегантно и красиво можно проектировать иерархию классов и интерфейсы объектов.
Итак, запишу ка пару выводов, которые недавно заимел :)

1. Итератор - это обобщение понятия указателя для работы с различными структурами данных стандартным способом.
Поскольку итератор является обобщением понятия «указатель», семантика у них одинаковая, и все функции, принимающие в качестве параметра итераторы, могут также работать и с обычными указателями. Это достигается за счет применения шаблонов.

Всего существует пять типов итераторов, на рисунке представлена их иерархия.

Читать далее...

Страницы