Нестандартное использование очередей

Общие принципы, проектирование, модуляризация, темплейты и шаблоны
Ответить
Artem.spb

Activity Автор
professor
professor
Сообщения: 3666
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 64 раза
Поблагодарили: 204 раза
Контактная информация:

Нестандартное использование очередей

Сообщение Artem.spb »

На паре ресурсов эта информация вызвала интерес и даже небольшие споры. Я подумал, что полезно поделиться знаниями и тут.

Очереди можно использовать «неправильно»
Мы же знаем, что очередь — это «первый пришёл — первый ушёл» (FIFO), и есть строгое правило: один или несколько производителей → один (и только один) потребитель. Это связано с тем, что при чтении элемента он удаляется из очереди, поэтому последующие попытки чтения будут неудачными. Возможно ли использовать очередь в сценарии одного производителя → множества потребителей?

Несколько лет назад у нас была задача распараллелить ресурсоёмкие вычисления: АЦП получал данные, которые нужно было прогнать через сложные алгоритмы. Был многопроцессорный серверный ПК, CPU был загружен на несколько процентов, но вычисления всё равно отставали и система не справлялась с потоком данным. Проблема была в том, что вычисления не были параллельными.

Несколько параллельных циклов решали проблему параллельности, но как организовать распределение задач? Как producer должен понять, в какую очередь отправить новую порцию данных? Флаги, обратная связь «я завершил вычисления»? Новые усложнения архитектуры. фуфуфу.

В итоге мы нашли элегантное решение. Каждый элемент из очереди можно забрать ровно один раз. Именно это нам и нужно! Один производитель и много потребителей. Как только один из экземпляров обработчика завершает очередной цикл, он встаёт в очередь на… чтение очереди.
По сути LabVIEW за нас занималось диспетчеризацией потоков.

В простом варианте это просто N параллельных циклов/SubVI. Если хочется чуть больше универсальности и привязать количество циклов к количеству процессоров, то можно запускать вычислители с помощью call-by-ref.

Так что, как говорили у нас в школе: если нельзя, но очень хочется, то можно.
q1.png
q2 copy.png
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5696
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 35 раз
Поблагодарили: 129 раз

Нестандартное использование очередей

Сообщение IvanLis »

Давай тогда я тоже перенесу обсуждение из Tg сюда, может кому пригодится.

Я несколько раз использовал очереди не по назначению, а для организации своеобразного "конвейера" - "псевдо параллельность".
Т.е. разбиваешь сложную вычислительную задачу на шаги. Каждый шаг выполняется в своем цикле.

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

Например у нас шесть шагов (циклов), когда первый получает седьмую порцию, последний досчитывает первую :clap: .
И если правильно декомпозировать задачу, то можно распределить вычисления между потоками.
Так и последовательность данных не нарушается, когда это важно и вычисления ведутся параллельно.

Вот пример и результаты тестирования:
lv2015.vi
(14.19 КБ) 11 скачиваний
lv2026.vi
(12.79 КБ) 8 скачиваний

Ubuntu 24.04lts + LV2026Q1
Linux.png
Видно, что в первом случае задача выполняется на одном ядре.
Во втором, сначала одно ядро, потом подключается второе и т.д.
Разница во времени более чем в 2 раза.

Windows 7 (VirtualBox) + LV2015
Win1.jpg
Win2.jpg
Artem.spb

Activity Автор
professor
professor
Сообщения: 3666
Зарегистрирован: 31 июл 2011, 23:05
Награды: 2
Версия LabVIEW: 12-18
Благодарил (а): 64 раза
Поблагодарили: 204 раза
Контактная информация:

Re: Нестандартное использование очередей

Сообщение Artem.spb »

IvanLis писал(а): 18 авг 2026, 14:02 Я несколько раз использовал очереди не по назначению, а для организации своеобразного "конвейера" - "псевдо параллельность".
Если уж не то пошло, ты используешь очередь по назначению: для передачи данных из одного цикла в другой :wink:
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5696
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 35 раз
Поблагодарили: 129 раз

Re: Нестандартное использование очередей

Сообщение IvanLis »

Artem.spb писал(а): 18 авг 2026, 15:05 Если уж не то пошло, ты используешь очередь по назначению: для передачи данных из одного цикла в другой :wink:
Согласен :danceto:
Ответить

Вернуться в «Модели программирования»