powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / std::async
25 сообщений из 50, страница 2 из 2
std::async
    #39755952
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
featureDima TТут все оптимально, но можно словить тормоз почти на порядок на ровном месте А какое отношение false sharing, размерность cache line и обеспечение cache coherence в родимой ccNUMA имеет к простаивающим тредам, удерживающих память под стэк и thread local storage?
Нифига не понял, пиши по-русски
...
Рейтинг: 0 / 0
std::async
    #39755953
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenDima TКак устроен std::async я не в курсе
Вопрос был по экспертизе в работе std::async без троллинга и с документированным и аргументированным обоснованием.

Однозначно отказаться от использования и вводить запрет на использование. Аспекты работы std::async недетерминированы, из-за чего использование такового в продакшене потребует постоянного контроля и излишних проверок.
...
Рейтинг: 0 / 0
std::async
    #39755954
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
featureАспекты работы std::async недетерминированы

А если я вместо  std::async создам вектор   std::thread и дождусь их выполнения ?

Это тру подход для прода ?
...
Рейтинг: 0 / 0
std::async
    #39755956
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
p.s.: процедура многопоточного выполнения запускается разово и нечасто
...
Рейтинг: 0 / 0
std::async
    #39755959
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenp.s.: процедура многопоточного выполнения запускается разово и нечасто
Оцени затраты. На калькуляторе дорого отдельный поток держать, холодильник - не знаю, а для обычного проца, даже телефона, это незаметно.
...
Рейтинг: 0 / 0
std::async
    #39755965
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semenА если я вместо  std::async создам вектор   std::thread и дождусь их выполнения ?
Это тру подход для прода?
Быстренько и по простому — это когда по одному треду на задачу, из-за того, что задач планируется максимум на сотню штук? Это всё равно «технический долг».
Завтра коллега отдаст этой подсистеме 100500 задач, в голову ему не могло прийти, что там создаётся по треду на задачу. Вроде и ничего страшного, ну сожрут сорок Гб виртуальной памяти. Косяк будет в накладных расходах на переключении контекста, когда шетдулер ОС пытается всем поровну выделить кванты процессорного времени. А начав активно писать по выделенным адресам памяти, эти треду вызовут в ОС лавину soft page fault'ов.

Самый простой и трушный подход для прода — это вектор тредов размерности (мощности множества) в N+1, где N = количество реальных ЦПУ в системе, без гипертрединга. Когда задачами эти треды кормяться из общего котла (очередь, стек, кольцевая очередь) с замком на крышке в виде std::shared_mutex — множество читателей и один писатель.
Хоть миллион задач придёт в эту подсистему, а весь солюшен в целом останется жизнеспособен. Напишет в лог с соответствующим северити (info/warning), что как-то шибко много задач, но будет их спокойно лопатить, не провоцируя ОС на аварийное завершение всего солюшена.

P.S.
Если уж ну совсем, с-о-в-с-е-м у-с-ё л-е-н-и-в-о и нормальным путём ну никак идти не получится, то хотя бы кидать эксепшен увидев слишком большое число задач перед тем, как создавать треды.
...
Рейтинг: 0 / 0
std::async
    #39755966
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
featuresemen.s.semenА если я вместо  std::async создам вектор   std::thread и дождусь их выполнения ?
Это тру подход для прода?
Быстренько и по простому — это когда по одному треду на задачу, из-за того, что задач планируется максимум на сотню штук? Это всё равно «технический долг».
Завтра коллега отдаст этой подсистеме 100500 задач, в голову ему не могло прийти, что там создаётся по треду на задачу. Вроде и ничего страшного, ну сожрут сорок Гб виртуальной памяти. Косяк будет в накладных расходах на переключении контекста, когда шетдулер ОС пытается всем поровну выделить кванты процессорного времени. А начав активно писать по выделенным адресам памяти, эти треду вызовут в ОС лавину soft page fault'ов.

Самый простой и трушный подход для прода — это вектор тредов размерности (мощности множества) в N+1, где N = количество реальных ЦПУ в системе, без гипертрединга. Когда задачами эти треды кормяться из общего котла (очередь, стек, кольцевая очередь) с замком на крышке в виде std::shared_mutex — множество читателей и один писатель.
Хоть миллион задач придёт в эту подсистему, а весь солюшен в целом останется жизнеспособен. Напишет в лог с соответствующим северити (info/warning), что как-то шибко много задач, но будет их спокойно лопатить, не провоцируя ОС на аварийное завершение всего солюшена.

P.S.
Если уж ну совсем, с-о-в-с-е-м у-с-ё л-е-н-и-в-о и нормальным путём ну никак идти не получится, то хотя бы кидать эксепшен увидев слишком большое число задач перед тем, как создавать треды.

Нет тут никакого параллелизма

Процедура запускается разово под жестким локом и никто в параллель ничего не делает.

То что число тредов = числу ядер это и обидчевому семену понятно.

Вопрос по С++

std::vector<std::thread>

bla bla bla

for ()
thread.join();

После выхода из метода ВСЕ созданные треды реально подохнут без всяких зомби и незакрытых хендлов ?
...
Рейтинг: 0 / 0
std::async
    #39755968
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semen,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
{
    std::vector<std::thread>

    bla bla bla

    for ()
    thread.join();
}
// здеся все треды «реально подохнут без всяких зомби и незакрытых хендлов»


т.е. за пределами local | function scope, если про объекты std::thread созданные на стэке.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
void doSomething()
{                                    <-------
     {                   <----               | 
                              |              |
         int a;           Local Scope    Function Scope
                              |              |
     }                   <----               | 
}                                    <------- 
...
Рейтинг: 0 / 0
std::async
    #39755971
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
featuresemen.s.semen,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
{
    std::vector<std::thread>

    bla bla bla

    for ()
    thread.join();
}
// здеся все треды «реально подохнут без всяких зомби и незакрытых хендлов»


т.е. за пределами local | function scope, если про объекты std::thread созданные на стэке.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
void doSomething()
{                                    <-------
     {                   <----               | 
                              |              |
         int a;           Local Scope    Function Scope
                              |              |
     }                   <----               | 
}                                    <------- 



Понял спасибо

И последний вопрос

Как правильно передавать исключения из созданных потоков в исходный тред ?

Я читал про std::promise, std:future,

что будет самым верным решением ?
...
Рейтинг: 0 / 0
std::async
    #39755980
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
semen.s.semen,

скорее выбор должен быть между std::promise и std::packaged_task, в обоих случаях std:future служит средством доступа к создаваемому шаренному состоянию.
вполне грамотно делать так:
Код: plaintext
1.
2.
3.
4.
5.
6.
std::packaged_task<int(int,int)> task( some_func );
std::future<int> result = task.get_future();
std::thread task_td( std::move(task), 2, 10 );
...
task_td.join();
... = result.get();



и да, кстати, платой за использование std::thread является хорошо известная неприятность — делать join() явно на каждый тред можно лишь когда гарантирована exception safety между вызовом join() и моментом создания треда. В остальных случаях следует использовать простенький самописный thread_guard, который при выбрасывания исключения (размотке стэка) сделает или join или detach для треда.
...
Рейтинг: 0 / 0
std::async
    #39755981
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Раз уж тут ведется такая познавательная беседа может и меня просвятят...
featureвектор тредов размерности (мощности множества) в N+1, где N = количество реальных ЦПУ в системе, без гипертрединга
Понимаю, что это правильно с теоритеческой точки зрения, но никогда не понимал как этого можно достичь на практике? Этот совет во всех книжках идет, но либо я - дурак, либо авторы этих советов живут в каком-то розово-плюшевом королевстве.

В современной ОС помимо тебя крутятся еще десятки приложений, поэтому процессор пусть и по чуть-чуть но загружен потоками в количествах измеряемых тысячами. Откройте свой менеджер задач и посмотрите сами, сколько там дескрипторов потоков открыто. Да, большинство из них спят, но чисто технически даже на 16 ядерном компе, удовлетворить условию "одно ядро - один поток" тысячеголовую араву потоков mission impossible, поэтому переключения контекстов неизбежно будут.

Возможно это правило относится к каждому из процессов и ОС, как-то по своему разруливает это на макроуровне процессов, но я нигде про это не встречал инфы. ОК, тогда один процесс - N+1 количество потоков - и так ДОЛЖНО БЫТЬ у каждого процесса, но опять же, как можно удовлетворить данному требованию в современной ОС? И речь даже не о том, что кто-то криворук или неграмотен и не следует "золотому' правилу.

Возьмем к примеру Windows. Современные программы уже никто не пишет с С++ библиотеками рассчитанными на однопоток, следовательно мультитред у нас уже заложен на уровне самой библиотеки компилятором. А это сильно развязывает ОС и прочим прилипалам к процессам руки. Современные ОСи по умолчанию включают в вашу программу собственный пул потоков процесса, не считая того, что программист к этому пулу может создавать свои собственные до кучу.

Кроме того, вот я запускаю свою службу. Служба по умолчанию должна работать в отдельном потоке управляемом SCM (то есть минус один поток из моей программы). Служба наверное не на святой воде работает и не для простоя предназначена, значит нужно проинициализировать ряд вспомогательных подсистем. Проинициализировал COM - хоп! и в твоем процессе еще один вспомогательный поток, который ты в явном виде не создавал (большинство пишущих формочки для форточек вообще про это не знают даже). Проинициализировал терминальный API - хоп! и еще один - Event ловушка. Кто-то решил кинуть глобальный хук - хоп! и к твоему процессу присосалось несколько DLL, который тоже могут жить в собственных потоках. Система постоянно что-то там тоже мониторит, счетчики считает PerfMon, Event'ы. И вот у тебя в потоке уже куча соседей, которых ты не приглашал (в явном виде)! Поэтому вместо 10 открытых дескрипторов ты стартуешь с нуля уже со 100-150 объектами ядра (не обязательно потоков) в твоем процессе, а потом сидишь и башку ломаешь, где же я столько ресурсов разлил!?

И т.д. поэтому когда я запускаю свое ПО и потом смотрю в Process Explorer'e на свои и чужие потоки, то я просто охреневаю , сколько желающих посидеть за мой счет!
Ну и что же у нас в таком случае остается от этой волшебной формулы.
Да ничего!

Если у тебя не Ryzen Threadripper какой-нибудь, а желательно 2-3 таких же.

Вот я и не понимаю, как я могу обеспечить это красивое N+1!
Это либо какой сферический конь в вакууме, либо я просто не умею его готовить.
...
Рейтинг: 0 / 0
std::async
    #39755984
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum,

А как же внимательность при потреблении информации с книжек и остальных мест?
Упоминаемое N+1 актуально лишь для активно работающих потоков, т.е. когда надо получить максимальное количество выполненной работы за единицу времени от машины с несколькими ЦПУ (физическими ядрами).

Все остальные треды в ОС или не участвуют в попытках получения квантов времени ЦПУ или же их потребности в вычислительных ресурсах незначительны и для них хватает побочных/второстипенных мощностей гипертрейдинговых потоков.
Современный ЦПУ x86 уже давно не CISC, а множество RISC-устройств в рамках каждого ядра. Отсюда и возможность выполнения более чем одного потока на одном ядре одновременно (гипертрединг).
...
Рейтинг: 0 / 0
std::async
    #39755987
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
feature,

да, я полностью согласен. Я это понимаю, что фактически их потребности ничтожны, как правило, пока никто не укладывает 1-2 ядра на лопатки.

У меня есть парк из нескольких сотен хостов, с которых при одном запросе я должен получить сведения. Например, это терминальники или веб серверы и программа по запросу от пользователя должна опросить их на предмет того, на каком из них сидит сейчас пользователь с ником ИванИваныч. Если я эти сотни буду опрашивать через пул потоков максимальной емкостью = кол-ву ядер, я просто могу сразу тогда идти заваривать кофе и советовать делать тоже самое тетям-менеджерам в саппорте. А параллельно с этим к программе прилетает еще десяток аналогичных запросов, требующих интенсивного общения с удаленными хостами и тогда они станут в очередь.

Поэтому, где могу я стараюсь придерживаться правильного подхода, но где-то он тупо неприменим. И как показывает моя практика не применим практически нигде. Я лучше организую десятка 3-4 медленно живущих потоков, чем буду постоянно надрючивать 8 завязанных по самое небалуйся. В каком-нибудь десктопном 1С, подход N+1 еще может взлететь, но в серверном сегменте, когда у тебя огромный парк техники - нужен какой-то другой подход. Поэтому у меня все свое - пулы, потоки, планировщики и пр. С std не связываюсь, потому что нужен за всем контроль.

За пренебрежение правилами приходится платить перекосом кода в сторону его проживания в режиме ядра, переключениями контекстов и лавин soft page fault'ов , с чем я пытаюсь по мере сил бороться, но все равно выходит так себе.
...
Рейтинг: 0 / 0
std::async
    #39755994
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum,

серверный сегмент с огромным парком техники — это когда число машин на несколько порядков больше, чем несколько сотен. Из своего личного, субъективного опыта, в таких системах прекрасно работают стандартные подходы и решения/паттерны.

Для примера, зачем плодить множество тредов в пуле, когда дело упирается в создание подсистемы асинхронных вызовов удалённых хостов, поверх пула tcp-коннекций, реализованных посредством неблокирующихся беркли-сокетов? Если такая система постоянно нагруженна обращениями, распределяя, отправляя и собирая их с удалённых хостов, то на кой лад в ней три десятка тредов на 16 ядрах?

Потому если проблему и искать, то именно в том человеке, что стоит у руля. По ряду причин с ним не хотят работать даже мало мальски приличные специалисты. Такое случается, когда человек самоучка прошедший некоторый путь, но в сфере фриланса, среди доморощенных специалистов «от сохи». Потому никогда не видел работы профессионалов и неспособен опознать, оценить предлагаемые ими решения. А профи не любят работать с теми, кто неспособен оценить их собственные уровень и вклад в проект.

В любом случае, это всё надо выводить в отдельный тред и обсуждать исходя из контекста отдельной предметной специфики.
...
Рейтинг: 0 / 0
std::async
    #39755998
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
feature,

Только все же наверно join, а не wait...
...
Рейтинг: 0 / 0
std::async
    #39755999
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CerebrumРаз уж тут ведется такая познавательная беседа может и меня просвятят...
featureвектор тредов размерности (мощности множества) в N+1, где N = количество реальных ЦПУ в системе, без гипертрединга
Понимаю, что это правильно с теоритеческой точки зрения, но никогда не понимал как этого можно достичь на практике? Этот совет во всех книжках идет, но либо я - дурак, либо авторы этих советов живут в каком-то розово-плюшевом королевстве.

В современной ОС помимо тебя крутятся еще десятки приложений, поэтому процессор пусть и по чуть-чуть но загружен потоками в количествах измеряемых тысячами. Откройте свой менеджер задач и посмотрите сами, сколько там дескрипторов потоков открыто. Да, большинство из них спят, но чисто технически даже на 16 ядерном компе, удовлетворить условию "одно ядро - один поток" тысячеголовую араву потоков mission impossible, поэтому переключения контекстов неизбежно будут.

Возможно это правило относится к каждому из процессов и ОС, как-то по своему разруливает это на макроуровне процессов, но я нигде про это не встречал инфы. ОК, тогда один процесс - N+1 количество потоков - и так ДОЛЖНО БЫТЬ у каждого процесса, но опять же, как можно удовлетворить данному требованию в современной ОС? И речь даже не о том, что кто-то криворук или неграмотен и не следует "золотому' правилу.

Возьмем к примеру Windows. Современные программы уже никто не пишет с С++ библиотеками рассчитанными на однопоток, следовательно мультитред у нас уже заложен на уровне самой библиотеки компилятором. А это сильно развязывает ОС и прочим прилипалам к процессам руки. Современные ОСи по умолчанию включают в вашу программу собственный пул потоков процесса, не считая того, что программист к этому пулу может создавать свои собственные до кучу.

Кроме того, вот я запускаю свою службу. Служба по умолчанию должна работать в отдельном потоке управляемом SCM (то есть минус один поток из моей программы). Служба наверное не на святой воде работает и не для простоя предназначена, значит нужно проинициализировать ряд вспомогательных подсистем. Проинициализировал COM - хоп! и в твоем процессе еще один вспомогательный поток, который ты в явном виде не создавал (большинство пишущих формочки для форточек вообще про это не знают даже). Проинициализировал терминальный API - хоп! и еще один - Event ловушка. Кто-то решил кинуть глобальный хук - хоп! и к твоему процессу присосалось несколько DLL, который тоже могут жить в собственных потоках. Система постоянно что-то там тоже мониторит, счетчики считает PerfMon, Event'ы. И вот у тебя в потоке уже куча соседей, которых ты не приглашал (в явном виде)! Поэтому вместо 10 открытых дескрипторов ты стартуешь с нуля уже со 100-150 объектами ядра (не обязательно потоков) в твоем процессе, а потом сидишь и башку ломаешь, где же я столько ресурсов разлил!?

И т.д. поэтому когда я запускаю свое ПО и потом смотрю в Process Explorer'e на свои и чужие потоки, то я просто охреневаю , сколько желающих посидеть за мой счет!
Ну и что же у нас в таком случае остается от этой волшебной формулы.
Да ничего!

Если у тебя не Ryzen Threadripper какой-нибудь, а желательно 2-3 таких же.

Вот я и не понимаю, как я могу обеспечить это красивое N+1!
Это либо какой сферический конь в вакууме, либо я просто не умею его готовить.

Ты вазе умеешь отличать работающий поток от простающего?

Это формула - для реально работающих.
...
Рейтинг: 0 / 0
std::async
    #39756000
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivfeature,

Только все же наверно join, а не wait...
Чего-чего?
Слово wait в треде ещё не встречалось.
...
Рейтинг: 0 / 0
std::async
    #39756011
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тут много инфы по теме
...
Рейтинг: 0 / 0
std::async
    #39756020
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

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

Самый быстрый код - это тот, который ты не стал писать.
Самый быстрый многопоток - в котором 1 или 0 потоков.
...
Рейтинг: 0 / 0
std::async
    #39756021
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
полудух,

спасибо, ознакомлюсь
...
Рейтинг: 0 / 0
std::async
    #39756025
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum,

вы правильно заметили, правильно заданый вопрос это половина ответа

кто лучше всего знает о состоянии загруженности ядер системы и нагрузке потоков?
ответ довольно очевиден: - ОС

что даёт ОС для решения этого вопроса
- автопул

что должен делать рантайм для оптимальной реализации выполнения?
- переложить неясные вопросы на ОС


отсюда первый вывод: в падавляющем большинстве случаев юзай согласно интерфейса и не парься до возникновения проблем

обнаружил затыки - оптимизируем дальше
считашь что планировщик ОС не справляется, нити в руки и сам менеджерь, написать свою точечную реализацию async хоть и напряжно, но вполне по силам среднему разрабу
...
Рейтинг: 0 / 0
std::async
    #39756268
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем всё это теоретизирование?

Достаточно взять нечто из вычислительных задач. Распараллелить расчёт на несколько тредов и посмотреть, при каком раскладе задача быстрее всего посчитается. Когда она распределена между 10 потоками на 8-ми ядерном ЦПУ или же, когда этих самых потоков 30 штук на той же самой системе. Чтобы уж совсем научно было, то повторить эксперимент не один раз и посмотреть какому распределению соответствует разница производительности между этими двумя подходами.

Это всё, в итоге, будет ответом про эффективность подходов многопоточности применимо к parallel computing.
Однако, есть ещё и concurrent computing , говорить о котором имеет смысл, лишь проведя такие же эксперименты.
...
Рейтинг: 0 / 0
std::async
    #39756283
Фотография полудух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как сказал Ульрих: не надо запускать 20 процессов с сотней потоков в каждом на машине с 16ю ядрами, это overpower. Не нужна такая крутая машина.
...
Рейтинг: 0 / 0
std::async
    #39756664
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
featureЗачем всё это теоретизирование?

Достаточно взять нечто из вычислительных задач. Распараллелить расчёт на несколько тредов и посмотреть, при каком раскладе задача быстрее всего посчитается. Когда она распределена между 10 потоками на 8-ми ядерном ЦПУ или же, когда этих самых потоков 30 штук на той же самой системе. Чтобы уж совсем научно было, то повторить эксперимент не один раз и посмотреть какому распределению соответствует разница производительности между этими двумя подходами.

Это всё, в итоге, будет ответом про эффективность подходов многопоточности применимо к parallel computing.
Однако, есть ещё и concurrent computing , говорить о котором имеет смысл, лишь проведя такие же эксперименты.конечно, и сразу с железом и своей ОС прогу поставлять
...
Рейтинг: 0 / 0
std::async
    #39757808
Фотография feature
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)конечно, и сразу с железом и своей ОС прогу поставлять
Пора привыкнуть к необходимости проверять, без жевания соплей и диванных теоретизирований. Продукт либо может эффективно работать в заявленной ОС и на заявленном железе, либо теоретиков гонят ссаными тряпками на улицу.
...
Рейтинг: 0 / 0
25 сообщений из 50, страница 2 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / std::async
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]