Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: Azazello от Сентябрь 20, 2019, 09:02



Название: std::async
Отправлено: Azazello от Сентябрь 20, 2019, 09:02
Иногда есть ситуативные задачи, когда можно распараллелить, и отослать его в std::async
Уточню: вроде и не планировали паралелить, но можно мелкую задачку закинуть.

А какие однозначные критерии для таких мелких! задач.

Вопрос: Как однозначно определить, в абсолютных цифрах, что накладные расходы на распаралеливание не превысят "выгоду".  Давайте считать, что у нас есть свободные ядра и система простаивает.

Да, могу протестировать на конкретной задаче, но может у кого есть "накопленный опыт"?.


Название: Re: std::async
Отправлено: Igors от Сентябрь 20, 2019, 10:35
Иногда есть ситуативные задачи, когда можно распараллелить, и отослать его в std::async
Уточню: вроде и не планировали паралелить, но можно мелкую задачку закинуть.

А какие однозначные критерии для таких мелких! задач.

Вопрос: Как однозначно определить, в абсолютных цифрах, что накладные расходы на распаралеливание не превысят "выгоду".  Давайте считать, что у нас есть свободные ядра и система простаивает.

Да, могу протестировать на конкретной задаче, но может у кого есть "накопленный опыт"?.
Предполагаю что с std::async - все упрется в конкретную реализацию платформы/компилятора. Справочник пишет
Цитировать
The template function async runs the function f asynchronously (potentially in a separate thread which may be part of a thread pool) and returns..
Т.е. какая нитка возьмется за выполнение задачи, будет ли она частью пула или создаваться всякий раз - хз, стало быть - на усмотрение реализации. Также видел упоминания что MSVC использует пул.

Более практичным (или предсказуемым) выглядит использование QThreadPool или boost::thread_pool. Рискну утверждать что с пулом будет никак не хуже. Совсем недавно (соседняя тема) делал замеры, они показали:

НА 4 ЯДРАХ (что я имею)
QThreadPool нормально "ускоряет" задачи со временем выполнения примерно до 20 МИКРО секунд, в принципе вполне достойный рез-т. Однако на задачах менее 10 МИКРО секунд наступает катастрофическое замедление (по сравнению с бесхитростным выполнением в главной нитке). Причем чем быстрее машина и чем больше ядер - тем хуже, больше замедление. Конечно все это имеет ощутимый эффект если таких "мелких" задач много, мульены, и они хорошо "весят" в общем времени выполнения.

Не полагайтесь на мой (или чей-то) "накопленный опыт", он получен на конкретной машине/платформе, обязательно промерьте сами.


Название: Re: std::async
Отправлено: m_ax от Сентябрь 20, 2019, 11:15
Цитировать
Однако на задачах менее 10 МИКРО секунд наступает катастрофическое замедление (по сравнению с бесхитростным выполнением в главной нитке). Причем чем быстрее машина и чем больше ядер - тем хуже, больше замедление.
Поэтому, может, прежде чем бездумно кидать в пул мильон "мелких" задач, стоит подумать о дизайне многопоточного приложения, или хотя бы попытаться реорганизовать задачи таким образом, чтоб сделать из мильона мелких, сравнительно небольшое их число но уже более жирных задач. Мы это уже обсуждали в соседней теме  :)

   


Название: Re: std::async
Отправлено: Igors от Сентябрь 20, 2019, 12:13
Поэтому, может, прежде чем бездумно кидать в пул мильон "мелких" задач, стоит подумать о дизайне многопоточного приложения,
Что стоит за этой назидательной фразой? По-моему аж ничего, так, "для красного словца"  :)

..или хотя бы попытаться реорганизовать задачи таким образом, чтоб сделать из мильона мелких, сравнительно небольшое их число но уже более жирных задач. Мы это уже обсуждали в соседней теме  :)
Есть народная примета: чем проще выглядит план - тем труднее его реализовать :) Несмотря на всю очевидность такого подхода, он частенько выливается в изрядный геморрой и немало загрязняет код. Да и применим не всегда, часто "копить" задачи нет смысла, нужно именно "бездумно сбросить", пусть ей сейчас же займется др нитка, потом заберем рез-т.

Кстати OpenMP сама "делает более жирные" по умолчанию


Название: Re: std::async
Отправлено: Azazello от Сентябрь 21, 2019, 15:05
Цитировать
Однако на задачах менее 10 МИКРО секунд наступает катастрофическое замедление (по сравнению с бесхитростным выполнением в главной нитке). Причем чем быстрее машина и чем больше ядер - тем хуже, больше замедление.
Поэтому, может, прежде чем бездумно кидать в пул мильон "мелких" задач, стоит подумать о дизайне многопоточного приложения, или хотя бы попытаться реорганизовать задачи таким образом, чтоб сделать из мильона мелких, сравнительно небольшое их число но уже более жирных задач. Мы это уже обсуждали в соседней теме  :)
    

Хех. Планирование - оно конечно хорошо. Но иногда такую злую шутку играет.
Впрочем, вопрос то стоял как раз о НЕЗАПЛАНИРОВАНОМ распараллеливании.
Так что соглашусь с Igors (его постом), и отдельное спасибо за конкретные цифры - все одно они относятся к x86 архитектуре, больше мне не надо.  

Другими словами, я так понял, профайлерами вы не пользуетесь. А если пользуетесь, то грош цена вашему проектированию :)
Шучу я, шучу!