пятница, 6 июня 2014 г.

[prog.c++] Простая реализация хамелеонов на SObjectizer

В продолжение вот этой темы. Не знаю, когда руки дойдут до создания аналогичного теста на Qt, т.к. Qt мне сейчас нужно изучать, фактически, заново. Но вот реализацию простого теста chameneos для текущего варианта SObjectizer-5 я сделал. Код можно посмотреть в репозитории на SourceForge, или же в конце этого поста. Целью же данной заметки является рассказ и объяснение на пальцах, как тест с хамелеонами реализуется в терминах SObjectizer-овских агентов, mbox-ов и сообщений.

Ниже обсуждается простой вариант теста, который когда-то использовался в The Computer Language Benchmark Game. Сейчас там применяется более усложненная версия, chameneos_redux. В принципе, при наличии на то необходимости и интереса, можно сделать и новую версию. Но я остановился на простой, т.к. когда-то уже делал ее реализацию на нескольких языках. Соответственно, если кто-то не в курсе, что такое тест с хамелеонами, то адресую интересующихся к своей практически уже мемуарной заметке на RSDN. Там описывается и условие задачи, и грабли, на которые легко наступить (причем, не только мне, как оказалось), решая ее с помощью низкоуровневых инструментов вроде мутексов, семафоров и условных переменных. Там же есть код моих решений этой задачи на C++ (с использованием ACE) и D1 (с использованием Tango).

Ну а тем, кому интересно, как такая задача решается на SO-5.2/5.3, добро пожаловать под кат.

[prog.c++] Безболезненная компиляция ACE с помощью MinGW

Есть такая большая C++ная библиотека -- ACE. И есть порты GNU GCC под Windows под общим названием MinGW (на самом деле их много, об этом ниже). Долгое время для меня был большой вопрос: как же работать с ACE вместе с MinGW?

Дело в том, что с оригинальным MinGW я уже много лет предпочитаю не связываться. Во-первых, какая-то там была очень мудреная система распространения -- сначала общие архивы со всем-всем-всем. Затем, напротив, куча мелких пакетиков. Хорошо хоть, в последнее время графический инсталлятор всего этого добра был доведен до работающего состояния. Во-вторых, сам оригинальный MinGW, как мне казалось, весьма сильно отстает от релизов unix-овских версий GCC. Например, насколько я могу судить, на mingw.org до сих пор лежат 32-битовые версии компилятора. Хотя альтернативные сборки (MinGW-w64, Win-builds, Nuwem, TDM-GCC) уже давно кроме 32- предоставляют и 64-битовые версии (в том числе GCC 4.8.3 и 4.9.0).

Поэтому, если мне нужно было что-то проверять под Windows GNU-тым компилятором, то я использовал Cygwin (который так же очень давно есть и в 32- и в 64-х битах).

Ну а вот на днях принципиально захотелось, чтобы ACE и SObjectizer собирались без проблем именно MinGW, а не Cygwin-ом. В итоге разобрался, что для этого нужно. В принципе, все это описано в штатной документации к ACE, но есть нюансы.

К сожалению, ключевой компонент, необходимый для нормальной компиляции ACE -- это MSYS, минималистическая имитация Unix-ового окружения под Windows. Я долгое время пытался вместо MSYS использовать Cygwin-овское окружение, но не прокатило. Поэтому без MSYS никуда и MSYS нужно брать с mingw.org.

Больше с mingw.org ничего не нужно, компилятор и библиотеки можно взять в другом месте. А вот MSYS придется искать и качать на mingw.org. Дабы не разбираться с кучей всего, что есть среди дистрибутивов mingw.org, можно воспользоваться графическим инсталлятором, в котором выбрать MSYS и позволить ему скачать и распаковать все самостоятельно.

После установки MSYS можно пойти двумя способами. Либо запускать MSYS среду посредством имеющегося в MSYS для этих целей bat-файла (у меня это C:\Original-MinGW\msys\1.0\msys.bat) и оказаться в готовом shell-е, а уже там настраивать все остальные пути. Либо же прописать в свой PATH путь к bin-каталогу MSYS-а (у меня это, соответственно, C:\Original-MinGW\msys\1.0\bin). Я пошел по второму пути, ниже объясню почему.
Upd. Можно воспользоваться и MSYS2. Я скачал msys2-base-x86_64, распаковал архив, прописал путь к msys2/bin в PATH. Далее через pacman установил пакет make, т.к. для ACE нужен GNU make, который идет в составе MSYS сразу, а вот в msys2-base его нет.
Сам же компилятор MinGW можно брать любой. Поскольку практически все перечисленные мной выше альтернативы оригинальному MinGW базируются на MinGW-w64, то можно только MinGW-w64 и ограничиться. Хотя у других дистрибутивов есть свои плюшки. Например, Nuwem вместе с MinGW-w64 ставит git, Boost и еще кучу всякой полезной в хозяйстве всячины. Win-builds так же вместе с MinGW-w64 предоставляет кучу библиотек, компиляция некоторых из них под Windows то еще удовольствие, так что к вариантам Nuwem и Win-builds рекомендую пристально присмотреться, если вам нужен не только ACE.

Для меня удобство MinGW-w64 состоит в том, что он распространяется в виде 7z-архива. Распаковываешь его куда удобно (в моем случае C:\mingw64) и все! Потом только добавляешь путь к его bin-каталогу в PATH. Если нужно обновить, то просто качаешь новую версию и распаковываешь ее.

Поскольку мне для компиляции SObjectizer вместе с ACE кроме MSYS и MinGW нужен еще и Ruby, то я настраиваю пути ко всему этому хозяйству в одном bat-файле, который содержит что-то вроде:

@set PATH=%PATH%;C:\ruby-2.0.0-p481-x64-mingw32\bin
@set PATH=%PATH%;C:\Original-MinGW\msys\1.0\bin
@set PATH=%PATH%;C:\mingw64\bin

После запуска своего bat-файла я получаю среду, в которой доступен компилятор MinGW и Unix-овые утилиты, необходимые для компиляции ACE.

Следующий очень важный шаг -- это определение переменной среды ACE_ROOT. Когда ACE компилируется под Visual C++ про ACE_ROOT можно забыть, а вот для MinGW его нужно выставлять. У меня для компиляции SObjectizer это делает Ruby-новый скрипт в рамках build-процесса внутри Mxx_ru. Но если вы компилируете ACE сами, то ACE_ROOT нужно прописывать ручками. Для этого удобно задействовать shell из MSYS, т.к. там проще работать с переменными среды, например, с $PWD.

Если ACE_ROOT выставлена правильно, то остается еще один важный нюанс: в make-правилах для компиляции ACE по умолчанию для GCC выставляется флаг -mtune=pentiumpro. И попытка собрать ACE 64-битовым GCC завершится сообщением об ошибке, т.к. модель оптимизации pentiumpro не совместима с режимом x86-64. Чтобы этой проблемы не было, компиляцию ACE нужно запускать задавая для make параметр TCPU=:

make TCPU= shared_libs=1 debug=0

Итак, резюмируя: обязательно нужен MSYS или MSYS2+make, обязательно нужно выставить переменную среды ACE_ROOT. И, при компиляции в x86-64 задать свое значение для TCPU при запуске make.

PS. Если ставить вручную MSYS и MinGW, то можно легко установить рядом 32-х и 64-х битовые версии MinGW, просто нужно иметь разные настройки для PATH. Это позволит проверять работу своих приложений как в 32-, так и в 64-х битовых режимах.

PPS. В составе MinGW-w64 есть дистрибутивы, помеченные как win32 и posix. Я проверял на win32-вариантах с SEH-обработкой исключений. ЕМНИП, с posix-вариантами ACE не компилируется, а выдает кучу ошибок по поводу ACE_WCHAR_T и char.

четверг, 5 июня 2014 г.

[prog.c++] Интересный макрос для объявления строковых констант в hpp-файлах

Увидел здесь: Lightweight HTTP Server in less than 40 Lines on libevent and C++11 . Признаюсь, раньше я не сталкивался с идеей использовать шаблонную структуру и ее специализацию для типа void. Сокращенный автономный пример, демонстрирующий и сам макрос, и результаты его применения:

#include <iostream>

#define DECLARE_STRING_CONSTANT(name_, value_) \
  namespace Private \
  { \
    template <typename T> \
    struct name_ \
    { \
      static char const Name[]; \
      static char const Value[]; \
    }; \
    template <typename T> \
    char const name_ <T>::Name[] = #name_; \
    template <typename T> \
    char const name_ <T>::Value[] = #value_; \
  } \
  typedef Private:: name_ <void> name_;

namespace Http
{
  namespace Request
  {
    namespace Header
    {
      DECLARE_STRING_CONSTANT(Accept, Accept)
      DECLARE_STRING_CONSTANT(AcceptCharset, Accept-Charset)
    }
  }
}

int main()
{
  std::cout << Http::Request::Header::Accept::Name << " -> "
      << Http::Request::Header::Accept::Value << std::endl;

  std::cout << Http::Request::Header::AcceptCharset::Name << " -> "
      << Http::Request::Header::AcceptCharset::Value << std::endl;
}

PS. Насколько я помню, в библиотеке POCO так же есть HTTP-сервер. Так что на POCO простейший HTTP-сервер, возможно, был бы еще короче :)

среда, 4 июня 2014 г.

[management.book] Дочитал таки "Структуру в кулаке" Генри Минцберга



Дочитал таки замечательную книгу Генри Минцберга "Структура в кулаке. Создание эффективной организации", цитаты из которой появлялись у меня в блоге в течении последнего месяца.

Книга сложная. Читать "с наскоку" и "запоем" не получится.

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

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

В общем, книга толстая, не простая, да еще и не содержит практических рекомендаций, которые можно взять и сразу же применить. Поэтому, если кто-то рассчитывает найти в ней готовые рецепты или готовые ответы на свои насущные организационные вопросы, то это напрасные ожидания.

Грубо говоря, можно провести такую аналогию. Допустим, вы хотите улучшить свою физическую форму или достичь каких-то спортивных успехов. Эта книга не даст вам конкретной методики тренировок или рекомендаций по правильному питанию или лучшей технике выполнения каких-то упражнений. Зато она позволит вам понять принцип. Т.е. прочитав ее вы поймете для каких условий предназначены конкретные методики, почему нагрузки нужно сочетать с отдыхом, на что можно рассчитывать выкраивая время на тренировки урывками и не имея возможности нормально питаться. Путь это грубое объяснение того, что можно найти в книге, но "на пальцах" объяснить как-то иначе очень сложно.

У меня самого ощущение по ходу чтения сильно менялось.

Сначала был ВАУ-эффект.

Потом пришло ощущение, что никакого правильного или научно обоснованного подхода к организации структуры нет в принципе. Все нужно решать по месту, здравый смысл рулит и если вам хочется иметь здоровую компанию, то нужно держать руку на пульсе, объективно оценивать происходящее, принимать решения исходя из вашей текущей ситуации, а не абстрактных и универсальных "правил и законов", а затем внимательно наблюдать за результатами и вносить корректировки в свои решения.

Вскоре после того, как я пришел к такому впечатлению, в книге пошел довольно сложный материал про горизонтальную и вертикальную специализацию и пр. вещи. И я едва не бросил чтение, настолько сложно мне давались главы в середине книги. Но, к счастью, удалось себя перебороть и продолжить чтение.

Вторая половина книги читалась под впечатлением "Ну надо же, все ведь давным-давно известно, так почему же, черт возьми!..."

По ходу чтения интересно было сопоставлять то, что пишет Минцберг с тем, что пишет Адизес. Одно время мне казалось, что Адизес по сравнению с Минцбергом -- это так, попса. Поверхностно и применимо только к небольшой части описываемых Минцбергом случаев. Но затем я изменил свое мнение. Думаю, что они оба описывают один и тот же очень большой и сложный объект, но используют его проекцию на разные плоскости. Поэтому картинка, т.е. сложность проекции, у них разная получается. Адизес уделяет внимание взаимосвязи личностных качеств и стадий жизненого цикла. А Минцберг -- общим правилам конфигурирования организаций, решающих разные проблемы и существующих в разных условиях. Каждая такая проекция дает лишь часть представления о проблеме. Но у Минцберга эта часть, несомненно, значительно больше. Хотя читать нужно и того, и другого.

Кстати говоря, мне показалось, что в одном месте и Адизес и Минцберг практически сошлись. Адизес у себя в "Управлении жизненным циклом корпорации" описывал идеальный сценарий развития компании: когда все начинается с интеграционной составляющей. Т.е. когда в организации сразу появляется "дух компании", а уже потом на эту основу накладывается все остальное -- цели, средства, способы управления и администрирования, и т.д. и т.п. Но уникальная атмосфера, ощущение причастности всех сотрудников, реальное работающее "компания -- это я", при движении компании по этапам своего жизненного цикла, возникает с самого начала и не исчезает -- это и есть идеальный маршрут по Адизесу. На мой взгляд, Минцберг в последней главе своей книги говорит о том же самом, называя такой стиль "миссионерским", т.е. у компании есть миссия и все сотрудники об этом не только знают, но и воспринимают миссию компанию как свою собственную. ИМХО, Адизес и Минцберг пишут об одном и том же.

Я рад, что мне повезло случайно наткнуться на эту книгу. Позволяет еще лучше понять то, что происходило и происходит в тех местах, где мне довелось работать.

Еще одно впечатление. Книга довольно старая, 1983-го года, т.е. изложенному в ней материалу уже больше 30 лет. И хоть книга не потеряла своей актуальности, но 30-ть лет -- это очень большой срок. Очень бы хотелось увидеть что-то вроде обновленного издания этой книги, в которой учтены особенности последнего времени. В частности, влияние на управленческие конфигурации со стороны крупных софтверных компаний (тех же Microsoft, Oracle, Google, Facebook, EPAM, Accenture и пр.). Ведь разработка софта -- это специфическая область, которая должна сочетать в себе черты механистической бюрократии, профессиональной бюрократии, адхократии и, наверняка, прямого управления... Впрочем, это тема для отдельного разговора.

PS. Я грозился более подробно расписать, почему выходцы из банков механистических бюрократий способны убить разработку софта в небольших продуктовых компаниях, базируясь на знаниях из книги Минцберга. Обязательно постараюсь со временем это сделать.

[life.photo] Прослушал мастер-класс Дмитрия Шатрова "Adobe Lightroom. Практика обработки фотографий"

Прослушал вчера мастер-класс Дмитрия Шатрова по практической обработке фотографий в Lightroom. Впечатления сложные. Попробую описать свои ощущения.


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

С другой стороны, я в некотором недоумении: насколько этот мастер-класс был полезен лично мне? Многое из того, что Дмитрий показывал, я либо уже и сам использую, либо знаю/видел, как используют другие. Поэтому ВАУ-эффектов было не много. Возможно, самое важное, что я вынес из этого урока -- это смелое наложение массы градиентов на изображение. Такого раньше я не видел, было поучительно. Плюс несколько очень полезных мелочей, за которые взгляд/слух зацепились при просмотре.

Наверное, если сравнивать с другими мастер-классами, которые я прошел в Profileschool, ощущение сухого остатка в данном случае оказалось минимальным. И тому, полагаю, есть очень важная субъективная (подчеркиваю, субъективная) составляющая, которую можно разбить на две части.

Во-первых, разность в подходах у разных мастеров. Например, Дмитрий Шатров начинает обработку фотографии с анализа гистограммы и приведение в норму параметров Exposure/Highlights/Shadows/Whites/Blacks/..., а потом уже выставление баланса белого. Исправление оптических искажений объектива делается еще ближе к концу обработки снимка. А вот Александр Довгуля, если мне не изменяет склероз, вообще не обращает внимания на гистограмму и рекомендует корректировать баланс белого, Exposure и Saturation с самого начала, при этом подчеркивая, что данные три параметра взаимосвязаны -- вытягивая одно теряешь другое и наоборот. Да и у меня самого выработался некоторый подход к обработке снимков, в котором первыми шагами являются Camera Calibration, Lens Profile Corrections, White Balans, а уже затем Exposure и Saturation (ну и далее по списку). При этом прекрасно понимаешь, что если ты знаешь, чего хочешь получить от снимка, то без разницы, какому авторскому подходу ты следуешь -- Шатрова, Довгули или своему собственному. Посему вопрос не в том, в какой последовательности двигать ползунки в LR, а...

...далее начинается, во-вторых. А именно, задаешься вопросом: а зачем он все это делает? Т.е. технические приемы преобразования изображения -- это круто. Но если тебе не кажется, что изображение в результате обработки становится лучше, то ты уже не столько обращаешь внимание на технику, сколько пытаешься найти для себя ответ на вопрос "А почему он думает, что так карточка стала лучше?" (по крайней мере такие вопросы у меня остались в отношении, как минимум, трех примеров обработки: тибетского монаха; первой ночной карточки, которая изначально была очень темная, и последнего фото из Африки с двумя сухими стволами деревьев).

Тут на 100% в дело вступает субъективность восприятия фотографии. Мне нравится одно, Дмитрию Шатрову другое. Он видит вот так, он умеет придавать снимкам тот вид, который считает правильным. Но у меня другой взгляд на вещи и большой вопрос в том, а будут ли показанные Дмитрием подходы к обработки фотографий полезны для меня лично.

Если же попытаться резюмировать, то мастер-класс мощный. Своих денег он стоит -- это однозначно. Требования к слушателям мастер-класса, полагаю, повыше среднего. Для того, чтобы воспринимать происходящее, нужно более-менее уметь пользоваться Lightroom-ом. Плюс к тому у Дмитрия довольно высокий темп изложения материала, это так же создает дополнительную нагрузку.

Однако, если вы уже проходили обучение у других мастеров и/или уже сами несколько раз пересматривали свой собственный подход к обработке фотографий, то будьте готовы к тому, что у вас может возникнуть желание поспорить с преподавателем :)

PS. Впечатления о всех мастер-классах, которые я проходил в школе Profile, можно найти по тегу Profileschool.

вторник, 3 июня 2014 г.

[management] Генри Минцберг об эффективности ориентированных на инновации организаций

Позволю себе еще одну довольно большую цитату из книги Генри Минцберга "Структура в кулаке". Но сначала нужно дать определение "адхократии", т.к. этот термин активно используется у Минцберга:
Сложные инновации требуют совершенно особой конфигурации, способной объединять специалистов разных профессий в слаженно функционирующие ad hoc (специальные) проектные команды. Пользуясь термином, получившим широкую известность благодаря работам Элвина Тоффлера, можно сказать, что эти организации являются адхократиями нашего общества.
Т.е. под адхократией понимается такая конфигурация организации, в которой нет жестких управленческих структур, разделения полномочий, долгосрочных планов и стратегий, формализованных систем контроля и стандартизации процессов/результатов и т.д. Вместо этого под конкретную насущную задачу создается проектная команда, которая сама выбирает наилучшие из возможных/доступных способов решения. Взаимодействие между командами в организации строится не на основе формальных процедур/процессов или же прямого управления "сверху", а посредством взаимного согласования.

Определение, конечно же, не полное. Но если кто-то работал в стартапе или в исследовательской лаборатории, то он более-менее представляет о чем идет речь.

Теперь еще один комментарий перед обещанной цитатой. Специально для читающих мой блог разработчиков и тестировщиков ПО, проджект- и других менеджеров, управляющих разработкой ПО или пытающихся выстраивать "процессы производства ПО". Цитируемая мной книга была написана в 1983-м году и является лишь упрощенным пересказом более объемной книги 1979-го года. Когда software development была еще не такой мощной и развитой индустрией, каковой она является в настоящее время. Но, я уверен, что те, кому приходится заниматься разработкой нового софта, найдут очень много знакомого...

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

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

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

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

[management] Бюрократии ориентированны на стандартный выпуск, а не на создание чего-то нового

Позволю себе еще одну небольшую цитату из книги Генри Минцберга "Структура в кулаке":
Результаты всех бюрократий во многом определяются стабильностью внешней среды; это исполнительские структуры, ориентированные на совершенствование программ действий для предсказуемых ситуаций, а не создание новых программ для решения незнакомых проблем.
Данное утверждение стало для меня ключом в понимании того, что в своем недавнем посте про результаты внедрения в маленькие софтверные компании ТОП-менеджеров из больших софтверных компаний и, в особенности, выходцев из банков, я лишь приоткрыл намного более глобальную проблему. И, полагаю, дочитав таки "Структуру в кулаке", я смогу высказаться на эту тему еще более предметно.
PS. И, кстати говоря, могу с полным на том основании предостеречь: не стоит писать подобные вещи в открытых местах, вроде Интернета, если вы не хотите потерять свою работу. Сложно представить себе, какие вещи будут использоваться против вас, если это кому-то потребуется. Так что не нужно самому на себя публиковать компромат ;)

понедельник, 2 июня 2014 г.

[life.photo] Портретно-репортажное с очередного этапа велогонок

В минувшее воскресенье поприсутствовал на 3-м этапе Кубка Гомеля по МТБ (велоспорту, короче) в качестве вольного фотоохотника. Наснимал много. Как водится, 70% отснятого материала сразу же ушло в корзину. То, что выжило после последующих фильтраций, можно увидеть в этом альбоме. Но там собраны все фотографии, безотносительно того, нравятся ли они мне или нет: я их оставлял не для себя, а для участников соревнований. А вот в данном посте я собрал те снимки, которые нравятся лично мне. Уж не знаю, как много зрителей разделяют мое мнение, но за эти снимки мне не только не стыдно, но я рад, что смог их сделать. Итак, кому интересно, милости прошу под кат. Полное же собрание сочинений от всех присутствовавших на гонке фотографов можно посмотреть вот здесь.