Обзор книги The Art of Multiprocessor Programming

The Art of Multiprocessor Programming

Книга написана в 2012 году, двумя авторами – Ниром Шавитом(Nir Shavit) и Морисом Херлихи(Maurice Herlihy). Как я уже упоминал ранее, книг, посвящённых многопроцессорной разработке, крайне мало и The Art of Multiprocessor Programming(TAMP), несомненно, является выдающимся экземпляром в области программирования многопроцессорных систем.

Так как многопроцессорные системы тема весьма широкая, книга не может охватить всё, что связаны с этими понятиями. И всё же авторы постарались максимально охватить эту область. Если попытаться в двух словах охарактеризовать содержание книги, то можно сказать следующим образом – это книга о блокирующих и не-блокирующих структурах данных и алгоритмах. Если вы не знаете, что это такое то это книга, безусловно, для вас.

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

Следующая глава посвящена регистрам, т.е. сущностям, которые поддерживают атомарные операции записи и чтения. В главе описана база, которая необходима для простейших конкурентных алгоритмов. Данная глава проще первых трёх, т.к. больше сосредоточена на практике, чем на голой теории. Правда глава 5 отыгрывается за это недоразумение вводя понятие консенсуса и описывая как важен он для конкурентных алгоритмов. В этой главе описывается почему read-write регистры практически бесполезны в конкурентных алгоритмах, почему даже read-modify-write не могут является достаточной базой, для реализации обобщённых конкурентных структур данных. Правда авторы занимаются не только тем, что уничижают различные техники они также приводят доказательство, что с помощью compare-and-swap операций, конкурентные структуры могут быть реализованы, без ограничений на количество одновременных пользователей(потоков). Как и другие главы с кучей теории,- эта глава показалось мне достаточно сложной.

Глава 6 посвящена применению консенсуса к созданию способов сериализации доступа к разделяемому ресурсу без блокировок(lock-free) и без ожидания(wait-free). На главе 6 заканчивается первая часть книги, по иронии судьбы эта часть также является наиболее сложной частью, лично для меня весь оставшийся материал книги был более-менее понятным(за исключением некоторой части 12-й главы, которая посвящена различным сложным структурам).

Главы с 7-й по 15-ю посвящены реализации различных структур данных, таких как стек, очередь, хэш-таблица и т.п. Некоторые из этих структур реализованы, в том числе, с помощью блокирующих механизмов, чтобы потом показать, как сделать их неблокирующими. Но все структуры в конечном итоге имеют, как минимум, неблокирующую реализацию, а в некоторых частях даже реализацию без ожидания. Весьма интересно наблюдать, как составляются неблокирующие структуры, даже если вы не собираетесь реализовывать их самостоятельно. Это полезно для понимания плюсов и минусов присущих неблокирующим структурам, что позволяет оценить когда их применение оправдано. Кроме того, это позволяет понять, что написание подобных алгоритмов дело весьма сложное и шанс совершить ошибку весьма велик. Это, безусловно, должно помочь в охлаждение жгучего желания велосипедостроения в область неблокирующих структур данных.

Главы 16-17 посвящены технологиям, которые в настоящее время активно используются при разработке ПО. Речь в них идёт о таких вещах как future, пул потоков(thread pool), планировщик(scheduler), барьеры(barriers). Последняя глава посвящена трансакционной памяти, которая является весьма перспективной технологией и в настоящее время активно прорабатывается на всех уровнях(ПО и железа). Большим плюсом этих глав является тот факт, что в книге приведена возможная реализация этих вещей, что позволяет глубже вникнуть в эти понятия. Кроме того, может быть интересно и дополнение B, в котором, в краткой форме, упоминаются различные части архитектуры компьютера, понимание которых чрезвычайно важно для правильного программирования многопроцессорных систем.

В целом мне книга понравилась, в ней описаны те вещи, без которых сложно уверенно программировать многопроцессорные системы. Конечно книга не для праздного чтения перед сном – чтобы понять описанные в ней вещи придётся вникать, но разве это плохо? Другое дело, что некоторые вещи можно было бы описать проще, привести больше примеров, нарисовать больше картинок и т.д.. Вообще примеры и картинки являются бичом этой книги, с моей точки зрения. Рисовать картинки к алгоритмам сложно, а к параллельным алгоритмам ещё сложнее и с этим, на мой взгляд, авторы не справились – картинки не очень понятны.

Есть у этой книги и ещё одна особенность – в примерах используется Java. С точки зрения понимания, это не составляет проблемы – я не знаю и никогда не писал на Java и я ни разу не пострадал от этого при чтении книги. Проблема тут в другом, если вы используете язык где управление памятью происходит явно(C++, к примеру), то использовать алгоритмы описанные в этой книге у вас так просто не получится, так как вопрос освобождения памяти будет стоять очень остро и для этого придётся использовать различные техники. В этом плане, безусловно, C++ Concurrency in Action выигрывает, т.к. описанные в ней алгоритмы можно брать и использовать без каких либо изменений(если мы говорим о C++). Но я бы не стал сравнивать эти книги в плане выбора или-или. Обе книги достойны и, хотя говорят об одном и том же, они совершенно разные. TAMP это куда более фундаментальный труд, чем C++ Concurrency in Action.

Чего вы не найдёте в этой книге: подробного описание архитектуры компьютера, из-за которой столько сложностей мы и имеем. Да есть краткое описание, но этого, для полноценного понимания, не достаточно. Книга именно что об искусстве программирования, сиречь высоком уровне, а не о том, как там всё под капотом устроено.

Таким образом мой вердикт будет следующим: книгу стоит прочитать всем тем, кто, обладая начальными знаниями в многопроцессорном программировании, хотел бы продвинутся на этом поприще дальше. Это книга для подготовленного читателя. новичку её читать не стоит, так как это может травмировать его психику :)