Многопоточность или задача параллельны библиотеке

У меня есть приложение, которое выполняет 30 независимых задач одновременно с помощью многопоточности, каждая задача получает данные по http, выполняет вычисление и возвращает результат потоку ui.

Я могу использовать TPL для выполнения тех же задач?

TPL создает 30 новых потоков и распространять их по всем доступным ядрам, или он просто разделяет задачи по доступным ядрам и использует один поток на ядро?

Будет повышение производительности с помощью TPL по многопоточности в этом случае?

8
задан Bruce Adams 26 March 2010 в 10:44
поделиться

4 ответа

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

По какой-либо причине вы не можете использовать асинхронную веб-загрузку? Я подозреваю, что здесь нет необходимости иметь поток на задачу или даже поток на ядро. TPL упрощает различные аспекты асинхронного программирования с помощью таких вещей, как продолжения.

С точки зрения эффективности, ваше приложение действительно ограничено процессором? Похоже, вам нужно получить максимально подходящий уровень параллелизма на сетевой стороне - это то, на чем следует сосредоточиться, если только вычисления не являются действительно тяжелыми.


ОБНОВЛЕНИЯ - НЕ ОТ ОРИГИНАЛЬНОГО АВТОРА

Приведенный выше ответ как всегда хорош, но может ввести в заблуждение, поскольку он не содержит некоторых важных изменений в .NET 4.0 CLR.

Как говорит Андрас, текущая реализация TPL использует пул потоков, следовательно, будет использовать столько потоков, сколько требуется ( количество ядер сейчас не имеет значения ):

Библиотека параллельных задач (TPL) - это коллекция новых классов , специально разработанных для упрощения и повышения эффективности выполнения очень мелких параллельных рабочих нагрузок на современном оборудовании. TPL уже некоторое время доступен отдельно как CTP и был включен в CTP Visual Studio 2010, но в этих выпусках он был построен на его {{ 1}} собственный выделенный планировщик работы . Для Beta 1 CLR 4.0 планировщиком по умолчанию для TPL будет пул потоков CLR , что позволяет рабочим нагрузкам в стиле TPL "хорошо играть" с существующими, QUWI. на основе кода и позволяет нам повторно использовать большую часть базовой технологии в пуле потоков - в частности, алгоритм внедрения потоков, который мы обсудим в будущем Почта.

Источник:

http://blogs.msdn.com/b/ericeil/archive/2009/04/23/clr-4-0-threadpool-improvements-part-1.aspx

9
ответ дан 5 December 2019 в 07:57
поделиться

Как правило, ничто не мешает TPL использовать больше (или меньше) потоков, чем ядра.

Чтобы немного контролировать ситуацию с помощью TPL, мой первый подход: убедиться, что параметр максимального количества потоков пула потоков составляет не менее 30, затем распараллелить задачу с максимальным уровнем параллелизма ] из 30. В задаче вы можете использовать семафор перед запуском вычислений с привязкой к ЦП, чтобы ограничить параллелизм числом ядер. Если вы не работаете под IIS или SQL-сервером, вы можете и, возможно, захотите установить минимальное / максимальное количество потоков пула потоков равным 30, чтобы предотвратить чрезмерное влияние эвристики пула потоков на количество потоков. (При условии, конечно, что TPL и пул потоков не используются для других целей в течение этого времени в вашем приложении.)

Оптимальное количество потоков зависит от ситуации. Рассмотрим, например, ваш сценарий: ваши задачи не привязаны к ЦП при извлечении данных - они привязаны к сети. При запуске задач было бы разумно увеличить параллелизм, чтобы загрузки выполнялись одновременно. Однако ваши расчеты могут быть связаны с процессором. В этом случае уменьшение количества потоков так, чтобы на каждом ядре выполнялся только один поток, может повысить производительность.

TPL теперь основан на новом пуле потоков CLR .
Пул потоков использует эвристику для определения количества потоков.
Есть видео Channel9 о новом пуле потоков с некоторой информацией.
Эвристику старого пула потоков и некоторые сведения о новом можно найти здесь (последний абзац «Что ждет в будущем?») .

Алгоритм и числа подвергались изменениям в разных версиях CLR.
Возможно, так будет и в будущем.

Есть много сообщений об уровне параллелизма, я наткнулся на здесь .

10
ответ дан 5 December 2019 в 07:57
поделиться

Вы порождаете 30 потоков? Используете ли вы пул потоков? Я полагаю, что tpl будет гораздо более оптимизированным. Порождение потоков - довольно дорогая операция. Я согласен с Джоном, что tpl обычно использует один поток на ядро. О какой версии .NET идет речь b.t.w.

0
ответ дан 5 December 2019 в 07:57
поделиться

У меня есть приложение, которое выполняет 30 независимых задач одновременно с использованием многопоточности, каждая задача извлекает данные через http, выполняет вычисления и возвращает результат в поток пользовательского интерфейса.

Это параллельная программа с привязкой к вводу-выводу.

Могу ли я использовать TPL для выполнения тех же задач?

Можно, но TPL разработан для параллельных программ с привязкой к ЦП, поэтому вы будете злоупотреблять им.

Создает ли TPL 30 новых потоков и распределяет их по всем доступным ядрам, или он просто разделяет задачи по доступным ядрам и использует один поток на каждое ядро?

Ни то, ни другое. TPL, по сути, использует очереди задач с перехватом работы без ожидания для каждого ядра для динамической балансировки нагрузки вычислений, интенсивно использующих ЦП, по мере их выполнения.

Будет ли в этом случае прирост производительности при использовании TPL по сравнению с многопоточностью?

Вы сэкономите 30 созданий потоков и дополнительную конкуренцию, вызванную вашими ненужными потоками.

Правильное решение вашей проблемы - написать асинхронную программу, которая не блокирует потоки. Это делается путем выражения оставшейся части ваших вычислений после завершения загрузки в виде продолжения, которое вызывается с данными после завершения загрузки.

Новый язык программирования Microsoft F # включает функции, специально разработанные для упрощения этой задачи. Например, ваша проблема может быть решена с помощью всего 5 строк кода на F #:

let fetchCalcAndPost uris calc post =
  for uri in uris do
    async { use client = new System.Net.WebClient()
            let! data = client.AsyncDownloadString uri
            do calc data |> post }
    |> Async.Start

Это решение никогда не блокирует ни один поток, поэтому он полностью параллелен.

2
ответ дан 5 December 2019 в 07:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: