пятница, 6 ноября 2015 г.

[prog.c++11] SObjectizer обновился до версии 5.5.10

Состоялся релиз версии 5.5.10. В этой версии реализована всего одна новая вещь: возможность указать, какой тип объекта синхронизации должен использоваться MPSC очередями сообщений.

До версии 5.5.10 SObjectizer использовал комбинированую схему блокировки на Multi-Producer/Single-Consumer очередях. Сперва consumer использует busy waiting на спинлоке. Но если не дожидается поступления новых событий в течении какого-то времени (приблизительно одну миллисекунду), то переключается на использование mutex-а и condition_variable. Такая схема отлично работает при высокой интенсивности обмена сообщениями между агентами. И, в частности, позволяет получать более высокие показатели в бенчмарках по сравнению с использованием только mutex/condition_variable.

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

Когда такой агент в приложении один, то затраты на busy waiting для его очереди событий невелики и ими можно пренебречь. Однако, если в приложении оказывается не один такой агент, а двадцать или тридцать, то оказывается, что даже когда агенты практически ничего не делают при обработке своих периодических сообщений, то приложение все равно отъедает 3-4% CPU. Ну а если таких приложений на одном сервере крутится десяток-другой, то затраты на "холостой" режим работы становятся совсем неприличными.

В версии 5.5.10 для ряда диспетчеров теперь можно задать фабрику объектов синхронизации. По умолчанию по-прежнему используется combined_lock, но можно задать и фабрику, создающую т.н. simple_lock (т.е. примитивная схема синхронизации на основе mutex/condition_variable). При использовании simple_lock_factory описанные выше агенты в "холостом" режиме вообще не потребляют процессорное время.

Технические подробности и примеры можно найти в Wiki проекта (за качество английского прошу не ругать, лабаю как умею, если кто-то может помочь с доведением качества документации до ума, то буду признателен).

Взять версию 5.5.10 можно с SourceForge, либо в виде архивов в секции Files, либо из Subversion-репозитория, или из зеркала на GitHub.

Прошу учесть, что на SF.net теперь выкладывается всего три zip-овских архива: с исходниками и с бинарниками (x86, x64) скомпилированными посредством VC++14.0. Если кому-то нужны другие архивы (например, бинарники собранные VC++12.0), дайте знать -- сделаем и выложим.

PS. Для двух диспетчеров, которые используют очереди Multi-Producer/Multi-Consumer, возможности указать фабрику объектов синхронизации пока нет. Это диспетчеры thread_pool и adv_thread_pool. Для них такая возможность будет реализована в версии 5.5.11, ориентировочно, через неделю.

PPS. Введение понятия lock_factory позволяет в будущих версиях SO-5.5 добавлять новые типы объектов синхронизации для очередей, а так же более гибко настраивать уже имеющиеся схемы блокировки. Например, можно сделать схему синхронизации исключительно на спинлоках с разными механизмами backoff-а, что может быть востребовано в приложениях, от которых требуется максимальная скорость обмена сообщениями. Плюс пользователь сам может создавать собственные фабрики и заставлять SO-5.5 использовать нужные пользователю объекты синхронизации. Так что тут есть куда двигаться, дело только за идеями и насущными потребностями :)

Комментариев нет: