Сообщение 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.
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.
VYR>на С# паралелил при помощи Parallel.For — какая-то жуть — накидывает 5% нагрузки в лучшем случае
VYR>а иногда так глючит что распараллеленый код выполняется за большее количество времени
VYR>что за хрень из-за чего?
Дело в том, что Parallel.For — под капотом довольно сложная вещь.
Помимо собственно параллельного выполнения она:
-Умеет обрабатывать exceptions и останавливает рабочие потоки, если в одном из них произошла ошибка
-Поддерживает несколько вариантов останова цикла (CancellationToken, ParallelLoopState.Break/Stop)
-Пытается оптимально балансить нагрузку, разбивая входные данные на диапазоны для независимой обработки и даже реализуя упрощенный work-stealing между этими диапазонами
Понятное дело, все это вносит накладные расходы.
Также, думаю понятно, что каким-бы умным ни был алгоритм балансировки в Parallel.For, он не вытянет против самописного алгоритма,
который досконально знает особенности входных данных, использует выделенные потоки (а не потоки из тред-пула) и в идеальном случае может вообще не тратиться на синхронизацию.
VYR>когда-то давно распараллеливал на С++ при помощи CreateThread — было просто чудо!
VYR>работа идеально делилась на количество потоков — ресурсоёмкости не добавлялась
Используй старый добрый System.Threading.Thread.