Информация об изменениях

Сообщение Re: распараллеливание и ресурсоёмкость от 16.04.2019 10:22

Изменено 16.04.2019 11:07 RushDevion

Re: распараллеливание и ресурсоёмкость
Здравствуйте, vvv848165@ya.ru, Вы писали:

VYR>на С# паралелил при помощи Parallel.For — какая-то жуть — накидывает 5% нагрузки в лучшем случае

VYR>а иногда так глючит что распараллеленый код выполняется за большее количество времени
VYR>что за хрень из-за чего?

Дело в том, что Parallel.For — под капотом довольно сложная вещь.
Помимо собственно параллельного выполнения она:
-Умеет обрабатывать exceptions и останавливает рабочие потоки, если в одном из них произошла ошибка
-Поддерживает несколько вариантов останова цикла (CancellationToken, ParallelLoopState.Break/Stop)
-Пытается оптимально балансить нагрузку, разбивая входные данные на диапазоны для независимой обработки и даже реализуя упрощенный work-stealing между этими диапазонами

Понятное дело, все это вносит накладные расходы.
Также, думаю понятно, что каким-бы умным не был алгоритм балансировки в Parallel.For, он не вытянет против самописного алгоритма, который досконально знает особенности входных данных, использует выделенные потоки (а не потоки из тред-пула)
и в идеальном случае может вообще не тратиться на синхронизацию.

VYR>когда-то давно распараллеливал на С++ при помощи CreateThread — было просто чудо!

VYR>работа идеально делилась на количество потоков — ресурсоёмкости не добавлялась
Используй старый добрый System.Threading.Thread.
Re: распараллеливание и ресурсоёмкость
Здравствуйте, vvv848165@ya.ru, Вы писали:

VYR>на С# паралелил при помощи Parallel.For — какая-то жуть — накидывает 5% нагрузки в лучшем случае

VYR>а иногда так глючит что распараллеленый код выполняется за большее количество времени
VYR>что за хрень из-за чего?

Дело в том, что Parallel.For — под капотом довольно сложная вещь.
Помимо собственно параллельного выполнения она:
-Умеет обрабатывать exceptions и останавливает рабочие потоки, если в одном из них произошла ошибка
-Поддерживает несколько вариантов останова цикла (CancellationToken, ParallelLoopState.Break/Stop)
-Пытается оптимально балансить нагрузку, разбивая входные данные на диапазоны для независимой обработки и даже реализуя упрощенный work-stealing между этими диапазонами

Понятное дело, все это вносит накладные расходы.
Также, думаю понятно, что каким-бы умным ни был алгоритм балансировки в Parallel.For, он не вытянет против самописного алгоритма,
который досконально знает особенности входных данных, использует выделенные потоки (а не потоки из тред-пула) и в идеальном случае может вообще не тратиться на синхронизацию.

VYR>когда-то давно распараллеливал на С++ при помощи CreateThread — было просто чудо!

VYR>работа идеально делилась на количество потоков — ресурсоёмкости не добавлялась
Используй старый добрый System.Threading.Thread.