> 1) прочитав все три твоих поста, не увидел ссылки > собственно на сам проект; > 2) «в пределах физически единой RAM, но с различными > адресными пространствами» — оно такое низкоуровневое, что > само рулит распределением виртуальной памяти скажем на > уровне ядра, эдакая OS в миниатюре? Могут ли эту штуку > использовать обычные приложения пользовательского режима? В > общем, хочется больше подробностей.
Понемногу информирую народ и приглашаю желающих.
Ниже выдержка из README, еще комментами добавлю декларацию целей и результаты одного из тестов.
One Hippeus, but THIS IS SPARTA!
= is an extreme performance messaging, nearly lockfree and zerocopy.
1Hippeus, aka One ippeuß,
= see http://www.biblestudytools.com/lexicons/greek/nas/hippeus.html
1Hippeus is a LGPL library, that act as framework and brings together:
+ efficient representation for chains of memory blocks with C++ iterators;
+ buffers management and allocation;
+ zerocopy & lockfree message pump and streaming;
+ operation with shared memory in different address spaces;
+ low-latency, realtime and priority inheritance;
=======================================================================
TODO:
- 0mq, netmap, dpdk.org & Infiniband/MPI as non-local transports;
- support for SPARC v9;
- Android Binder;
- Cross Memory Attach - http://lwn.net/Articles/405284/
- KNEM - http://runtime.bordeaux.inria.fr/knem/
Если чуть более детально, то отличия от конкурентов такие:
1. hippeus быстрее всех при использовании XADD, но при этом теряет свойство lockfree, т.е. строго говоря становится ближе к obstruction-free.
2. однако, при двух писателях/читателях hippeus гарантирует lockfree и примерно вдвое быстрее очереди Вьюкова ивсехизвестных очередей.
3. hippeus не требует памяти для хранения sequence для каждого элемента, т.е. очередь из uintptr_t требует вдвое меньше памяти.
4. при работе в lockfree режиме hippeus-очередь также использует одну CAS-операцию, при этом скорость падает до очереди Вьюкова.
5. в сравнении с очередями из FreeBSD, также одна CAS-операция, но без необходимости отключения preemption на время push/pop.
6. в сравнении с DPDK, также одна CAS-операция, но без риска busyloop при вытеснении потока посередине push/pop, другими словами DPDK очереди obstruction-free, а в 1Hippeus гарантируется lockfree.
7. в отличии от очереди NatSys-Lab (http://www.linuxjournal.com/content/lock-free-multi-producer-multi-consumer-queue-ring-buffer) в режиме использования XADD и конкурентном overflow/underflow выполняется откат с "инвалидацией" отдельных позиций в очереди. Поэтому вероятность сваливания в obstruction-free существенно меньше. Более того, как уже отметил, текущая реализация "инвалидатора" гарантирует lockfree для двух писателей/читателей (внутри один интервал, а не список).
8. еще одно отличие от NatSys-Lab в использовании 32-битных указателей "по модулю", а не 64-битных с гарантированным крахом при переполнении. Такое переполнение конечно скоро не случится, зато реализация хорошо ложится на 32-битные архитектуры.
9. на основе PI-futex-ов есть механизм передачи квантов времени "заснувшим" продьюсерам или консьюмерам, грубо говоря автоматический yield(), который опционально отключается.
Название выбрано с минимальным символизмом.12.04.14 16:58 Автор: leo <Леонид Юрьев> Статус: Elderman
Название выбрано с минимальным символизмом.
1Hippeus или One ippeuß – это всадник в войсках Спарты.
Спарта – потому что все жестко и без компромиссов. Один – как бы первый, чемпион и даже «один в поле воин».
А еще саркастически можно называть «гипоконем», «гиппопотамом» или «конем в вакууме»
ЦЕЛЬ №1
Предоставить предельно эффективную библиотеку для обмена сообщениями в пределах физически единой RAM, но с различными адресными пространствами.
Это подразумевается возможность обмена между разными процессами, между процессом (user-mode) и ядром (kernel-mode), между основным процессором (CPU) и сопроцессором (GPU, Tesla, Xeon-Phi), между процессами в пределах одного гипервизора. Подобных средств уже существует масса, но картина полностью меняется если решать задачу действительно предельно оптимально.
Например, MPI является ближайшим промышленным решением, но в случае локального обмена производится копирование данных. Соответственно 1Hippeus, напротив, ориентирован на поддержку zero-copy, т.е. на обмен через разделяемую память. Эта тонкость кардинально влияет на дизайн, делая 1Hippeus непохожим на другие решения.
Если допустить, что в перечисленных в самом начале случаях затраты на отправку/приём сообщения будут соизмеримы с вызовом функции, то это позволит изменить парадигму взаимодействия компонентов/служб.
Другими словами, «Игра стоит свеч» если только свести все накладные расходы (формирование сообщений, копирование данных, проводка через очередь) к величине сравнимой с затратами на вызов функции (в терминах языка С).
Поэтому «Цель №1» можно переформулировать как «Создать библиотеку для формирования сообщений и последующего обмена ими, с затратами соизмеримыми с вызовом функции».
ЦЕЛЬ №2
Получаемый набор примитивов и рецептов, также позволяет выстроить обмен непосредственно с DMA-дескрипторами сетевых адаптеров и интегрироваться с другими механизмами/библиотеками передачи сообщений.
Поэтому логично сразу предоставлять интерфейс и средства для такой интеграции, что позволяет рассматривать 1Hippeus как высокопроизводительный механизм обмена сообщениями в многопроцессорном кластере (Tilera, NUMA, RDMA).
Соответственно «Цель №2» звучит как «Предложить эффективный унифицированный интерфейс и средства интеграции с другими механизмов обмена сообщениями».
ЦЕЛЬ№3
Надежность, во всех смыслах. Библиотека должна быть надежной и стабильной.
Поэтому строенные средства контроля, мониторинга и отладки. Поэтому CI и автоматизированное тестирование. Поэтому политика релизов и OpenSource (будет).
КАК?
Обозначенные «благородные» цели трудны, но достижимы. Однако, для этого требуется подчинить весь дизайн производительности и хорошо продумать форму самих сами сообщений, чтобы манипулировать ими столь эффективно. При ответе на вопрос «как» проясняются трудности и цена, которую приходиться платить за эффективность. Становятся понятными use cases, получаемые плюсы и минусы.
Стоит отметить, что нет смысла разрабатывать решение, требующее сериализации объектов или копирования данных в памяти. Дело как в потере эффективности, так и в том что таких решений уже масса. Аналогично, бесполезны сообщения в виде простых ординарных типов данных, требуется что-то более гибкое и «резиновое» размещаемое в разделяемой памяти.
Сообщения в виде линейных участков памяти позволяют решить массу задач, но одновременно являются препятствием для эффективного обмена объектами, так как во многих случаях требуют сериализации (преобразования в последовательность октетов). Поэтому 1Hippeus для полезных данных предлагает «вязанки» буферов в разделяемой памяти, пересылаемое сообщение является указателем на такую «вязанку».
Пожалуй, уже можно обозначить основные части 1Hippeus и пояснить их взаимодействие:
1) Buffers: Управление буферами в разделяемой памяти, выделение и освобождение, подсчет ссылок.
2) Lace: Формирование «вязанок» и манипуляции с ними, включая итераторы и примитивы для помещения в «вязанки» более сложных объектов.
3) Queues: Очереди сообщений в разделяемой памяти, отправка и получение «вязанок».
Стоит заменить, что все составляющие ориентированы на эффективную работу в многопроцессорной среде, по возможности используются Lockfree/Waitfree алгоритмы и т.д.
Нельзя не сказать о трудностях, из которых можно выделить две главные:
= Взаимодействие из разных адресных пространств заставляет не использовать прямые указатели и требует прозрачности/подконтрольности всего кода. Соответственно нельзя использовать стандартные/готовые библиотеки или системные сервисы, включая примитивы синхронизации. Всё это приходится делать с чистого листа.
= При взаимодействии через разделяемую память ошибка одного из участников может легко сломать весь «оркестр». Соответственно требуется встроенные средства контроля целостности и выявления подобных ошибок, а также предоставление «безопасного режима» для отладки клиентского кода.
Два тупых вопроса появилось14.04.14 10:13 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 14.04.14 10:14 Количество правок: 1
1) прочитав все три твоих поста, не увидел ссылки собственно на сам проект;
2) «в пределах физически единой RAM, но с различными адресными пространствами» — оно такое низкоуровневое, что само рулит распределением виртуальной памяти скажем на уровне ядра, эдакая OS в миниатюре? Могут ли эту штуку использовать обычные приложения пользовательского режима? В общем, хочется больше подробностей.
Есть презентация точнее slidecast, где ближе к концу кратко...14.04.14 11:32 Автор: leo <Леонид Юрьев> Статус: Elderman
> 1) прочитав все три твоих поста, не увидел ссылки > собственно на сам проект; > 2) «в пределах физически единой RAM, но с различными > адресными пространствами» — оно такое низкоуровневое, что > само рулит распределением виртуальной памяти скажем на > уровне ядра, эдакая OS в миниатюре? Могут ли эту штуку > использовать обычные приложения пользовательского режима? В > общем, хочется больше подробностей.
> 1) прочитав все три твоих поста, не увидел ссылки > собственно на сам проект; > 2) «в пределах физически единой RAM, но с различными > адресными пространствами» — оно такое низкоуровневое, что > само рулит распределением виртуальной памяти скажем на > уровне ядра, эдакая OS в миниатюре? Могут ли эту штуку > использовать обычные приложения пользовательского режима? В > общем, хочется больше подробностей.
Вопросы - это хорошо.
Позволяют понять что нужно переформулировать или уточнить.
1) Исходники я пока не открыл. Хочу доделать примеры использования и тесты производительности.
2) Низкоуровневого много, но не все. Большие куски RAM запрашиваются у системы на стадии запуска. Далее самостоятельно alloc/release в lockfree режиме. При этом уже каждое приложение или модуль ядра имеет доступ ко всему "большому куску", через свое виртуальное адресное пространство. Другими словами, после выделения участка-пула памяти и его "декларации" как разделяемого любое приложение и модуль ядра имеет к нему доступ, конкурентно запрашивает и освобождает там буфера и прочее.
Аналогично с очередями, буферами, "вязанками" буферов и т.д. - все в разделяемой памяти, с offset_ptr внутри, без vmt.