Потоки могут работать на разных процессорах или ядрах как для Task.Factory.StartNew, так и для Parallel.Invoke - PullRequest
0 голосов
/ 07 ноября 2018

Я хочу уточнить мое понимание многопоточности .NET и, в частности, какие методы .NET создают потоки, которые могут потенциально выполняться одновременно на разных процессорах или ядрах в многопроцессорной / базовой системе.

В платформе .NET TPL вы можете использовать методы Parallel.Invoke или Task.Factory.StartNew для достижения некоторого параллелизма.

Насколько я понимаю, в обоих случаях .NET создает новые Задачи (за кулисами для Parallel.Invoke), которые затем среда .NET выделяет управляемым потокам за кулисами, которые затем назначаются потокам, которые ЦП может выделять разные ядра или процессоры в зависимости от рабочей нагрузки. Основное различие между этими двумя методами заключается в семантике - Parallel.Invoke выполняет несколько задач и ожидает их завершения; Task.Factory.StartNew запускает новую задачу в фоновом режиме. В обоих случаях реальная работа может выполняться на разных ядрах или процессорах. Согласно Task Parallel Library (TPL) .

У меня есть коллега, который убежден, что только метод Parallel.Invoke позволяет выполнять потоки на разных ядрах / процессорах, и что Task.Factory.StartNew запускает новый поток, но этот поток будет запланирован только на одном ядре. / процессор - так что фактически не дает параллелизма.

Я не могу найти какую-либо документацию или статьи, в которых прямо указано, так ли это на самом деле. Мой коллега направляет меня к тем же статьям, которые я просматриваю, например, Асинхронное программирование на основе задач , которые, как мне кажется, подтверждают мое понимание, но мой коллега считает, что он подтверждает его.

В документации иногда используется термин «параллельная обработка» со ссылкой на Parallel.Invoke и «асинхронные задачи» со ссылкой на «Task.Factory.StartNew», но, насколько я понимаю, то же самое происходит в фоновом режиме в отношении для выделения нескольким процессорам / ядрам.

Может кто-нибудь, пожалуйста, помогите прояснить ситуацию, по возможности со ссылками на документацию / статьи.

Я знаю, что это звучит как попытка разрешения спора с коллегой, но я искренне хочу уточнить, правильно ли я понимаю или нет.

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Хотя операционные системы иногда предусматривают «привязку процессора», это крайний случай, и его использование (или доступность) довольно редко. Насколько мне известно, .NET не использует подобные вещи.

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

0 голосов
/ 07 ноября 2018

На самом деле довольно легко ответить.

Task.Run ()

Поставляет в очередь заданную работу для запуска на ThreadPool ....

Задача параллельной библиотеки

... Кроме того, TPL обрабатывает разбиение работы, планирование потоков в ThreadPool, ....

Используя тот же ThreadPool, как ThreadPool может определить тип задачи для ограничения ЦП? Либо они оба работают на всех процессорах, либо все они работают на одном процессоре.

Дополнительный кредит:

Напрашивается вопрос, Знает ли ThreadPool Multi-Core ?

Ответ удивительно, ему все равно. ThreadPool запрашивает у операционной системы (как и любое приложение c #, которое использует new Thread()) для потока, это на самом деле ответственность ОС. Я думаю, к настоящему времени было бы совершенно ясно, что при всей абстракции, даже предполагающей, что C # может по умолчанию ограничивать использование потоков, это довольно нелепое утверждение. (Да, вы можете запустить поток на любом ядре и т. Д. И т. Д., Но это не так, как работает ThreadPool по по умолчанию ).

Я настоятельно рекомендую прочитать StartNew is Dangerous ... TLDR? Используйте Task.Run().

...