Ускорить С++ блокировку очереди и общую очередь

Я новичок в многопоточном программировании, я просто знаю самую распространенную Producer-Consumer-Queue. Я использую библиотеки boost С++, и я не знаю, лучше ли использовать boost:: lockfree:: queue или класс оболочки вокруг std:: queue, который использует `mutex` и` condition_variable`.

Где лучше использовать блокирующие данные структуры данных, и где лучше использовать простую реализацию на основе `mutex` и` condition_variables`?

Ответ 1

Попробуйте оба приложения, посмотрите, какие из них лучше всего работают.

Как правило, опрос блокировки без очереди работает лучше всего, когда очередь почти всегда имеет записи, блокирующая очередь работает лучше всего, когда очередь почти всегда пуста.

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

Недопустимость неблокирующих очередей - это отходы ЦП и пропускной способности памяти при опросе пустой очереди. Это можно смягчить, проектируя систему так, чтобы очередь была редко пуста.

Как уже намекали комментаторы, неблокирующая очередь - очень плохая идея для однопроцессорных систем.

Ответ 2

(Справочная)

Начиная с версии 1.54, вы должны знать некоторые требования

boost::lockfree::queue

  • T должен иметь конструктор копирования
  • T должен иметь тривиальный оператор присваивания
  • T должен иметь тривиальный деструктор

boost::lockfree::stack

  • T должен иметь конструктор копирования

boost::lockfree::spsc_queue

  • T должен иметь конструктор по умолчанию
  • T должен быть скопирован

Ответ 3

Вы также можете использовать свободную от очереди очередь, чтобы избежать инверсии приоритета в приложении реального времени.

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

Ответ 4

Решение сводится к задаче вопроса: "будет ли блокировка конфликта проблемой для решения задачи?"

Блокировка в параллельной среде затрагивает две различные проблемы.

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

Эти две проблемы - антагонистические цели. Классический подход заключается в защите общей структуры данных с помощью глобальных шлюзов. Это обеспечивает 100% -ную правильность, но это предотвращает увеличение производительности и особенно уровень concurrency выше определенной степени, поскольку общие блокировки приводят к "перегрузке трафика"

Кстати, вам нужно быть осторожным при использовании термина "lock free". Строго говоря, совлокальные операции никогда не могут быть на 100% свободными. Но возможно организовать сотрудничество с умом, чтобы уменьшить влияние блокировки на те партнеры, которым действительно нужно обращаться к одному и тому же элементу одновременно.