В каких случаях лучше использовать lockfree структуры данных, а когда на мютексах?

Необходимо реализовать multiple writer single reader queue.
Сразу нагугилось boost::lockfree::queue. Мне для этого никогда не приходилось использовать lockfree алгоритмы. Вот стало интересно в каких случаях предпочтительнее их использовать.
  • Вопрос задан
  • 4538 просмотров
Решения вопроса 1
@degs
Это сильно зависит от задачи, в общем случае lockfree алгоритмы позволяют передавать сообщения без блокировки читающего/пишущих потоков и получить задержку < 1 мкс на сообщение. Если у вас именно такие технические требования, то boost::lockfree вероятно единственный портабельный вариант.
Однако, если вас интересует скорость передачи (а не задержка в терминах мкс/на сообщение), то обычная блокирующая очередь ничем не уступит по параметру собщений/сек.
Еще один вариант применения - если вам нужно как можно быстрее освободить пишущий поток (типичный пример - логгер), тогда неблокирующая очередь - самый оптимальный алгоритм.
Обратите также внимание на то что boost::lockfree, как и все другие реализации, не предоставляет способа синхронизации читающего потока, то есть он будет непрерывно работать тратя ресурсы CPU. Если же вы искуственно его синхронизуете, например на мьютексе, то lockfree очередь выродится до обычной блокирующей. Еще из недостатков, существующая имплементация жестко ограничивает типы данных в очереди, простые данные с побитовым копированием и без конструктора, это очень ограничивает варианты дизайна.
Моя рекомендация - если у вас нет очень жестких специфических требований на пердачу данных, используйте обычную очередь.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
AxisPod
@AxisPod
На деле всё очень сложно и часто без 2х реализаций сказать очень сложно. На жесткой гонке lock-free могут очень плохо себя показать, т.к. будут постоянно болтаться во внутренних циклах, пытаться записать данные, при этом другие потоки будут влезать и мешаться. Опять же всё зависит от того как использовать. Например вряд ли будет выгодным вытаскивание из одной очереди 5-10 элементов на одно действие, т.к. будет в лучшем случае 10-20 lock-free операций со сбросом кэша, тут выгоднее даже будет spinlock mutex.
Ответ написан
Комментировать
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Мне казалось что вся соль lock-free алгоритмов раскрывается тогда, когда критическая секция отрабатывает за время меньше чем требуется на переключение контекста. Скажем если у вас запись в файл разруливается - то можно и старый добрый мютекс применить без всяких там спинлоков, потому что писать он будет явно дольше чем переключается контекст. А если у вас доступ в буфер какой разруливается или в очередь, то тут lock-free будут сильно эффективнее.

Так же при большом количестве потоков и высоком уровне конкуренси lock-free предпочтительнее.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы