2010-11-04 2 views
3

Я новичок в многопоточности, и я работаю над распараллеливанием области в своем приложении. Я прочитал несколько сообщений на этом сайте, но я все еще запутался в отношении наилучшего подхода к моей проблеме:Основные многопоточные вопросы в C#

[1] В .NET 3.5 есть ThreadPool, единственный способ для программы использовать многожильные в машине? т. е. возможно ли создавать потоки на разных сердечниках с использованием new Thread()?

[2] Мое дело: У меня есть List<Calculation>, который содержит около 80 элементов, обрабатываемых в настоящее время последовательно. Поэтому, учитывая, что я использую .NET 3.5 и на основе того, что я прочитал, ThreadPool, вероятно, мой лучший выбор для многопоточного из-за большое количество нитей, однако:

  • Существует много зависимости между Расчеты. В настоящее время список упорядочен таким образом, что все необходимые вычисления выполняются в начале.

Это как зависимость рабочих элементов выглядит (подробности не важно, просто хотел, чтобы сделать точку на сложности зависимостей):

alt text

  • раз Расчет являются значительно отличается, один объект Calculation может просто включать извлечение значения, другие объекты расчета будут включать много работы в вложенных циклах ... и т. д.

Как определить приоритет основного Calculations, который имеет что-то вроде 10+ других рабочих элементов в зависимости от этого? Каков наиболее эффективный способ сигнализации?

спасибо.

Редактировать: Следует отметить, что List<Calculation> остается фиксированным. Однако вычисление вычислений 80+ называется x миллион раз. Каждый раз, когда итератор обновляется, Calculate() вызывается на каждом Calculation в списке.

+1

Я не думаю, что вы можете перейти на .NET 4.0? PLINQ - это классно для подобных вещей. – StriplingWarrior

+3

Ваше изображение слишком мало, чтобы его можно было прочитать! –

+0

@ Майкл: Я сделал это нарочно. Я просто пытался понять сложность зависимостей. Вы можете придать рисункам свои ярлыки! – alhazen

ответ

1

[1] В .NET 3.5, это ThreadPool единственный путь для программы для использования мульти-ядер в машине? т. е. возможно ли создавать потоки на разных ядрах с помощью нового Thread()?

Это зависит от операционной системы, чтобы решить, какое ядро ​​должно работать. ОС по умолчанию распределяет потоки равномерно по нескольким ядрам (по крайней мере, в окнах).

ThreadPool используют один и тот же вид нитей как Thread класса, так как есть на самом деле только один вид (но различные типы классов и алгоритмов оборачивать их)

[2] Мой случай: у меня есть Listthat содержит около 80 элементов, которые в настоящее время обрабатываются последовательно. Поэтому, учитывая, что я использую .NET 3.5 и на основе того, что я прочитал, ThreadPool, вероятно, мой лучший выбор для многопоточной из-за большого количества нитей, однако:

Использование ThreadPool.QueueWorkItem, кажется, самый простой способ конвертировать ваше приложение.

Имейте в виду, что запуск 100 различных потоков не означает, что ваше приложение будет в 10 раз быстрее, чем работает 10 потоков. Скорее всего, что 10 потоков будут быстрее запускать синусоидальные операции, если фоновые события происходят, когда .net и ОС переключаются между потоками.

  1. Я хотел бы преобразовать List в Queue
  2. При запуске ваших расчетов, добавьте 10 (или любой номер, который вы хотите) вызовы ThreadPool.QueueWorkerItem (MyMethod);
  3. В MyMethod создайте цикл, который продолжает деактивировать элементы из вашей очереди, пока не осталось больше заданий.
2

[1]: Да, можно создавать потоки на разных ядрах с помощью new Thread(), хотя вам может быть лучше, если использовать threadpool. Различия обсуждаются здесь:

Thread vs ThreadPool

+0

Спасибо. Ссылка на блог (http://blogs.msdn.com/b/pedram/archive/2007/08/05/dedicated-thread-or-a-threadpool-thread.aspx) говорит, что выделенный поток будет лучше, чем используя ThreadPool, когда требуется иметь поток с определенным приоритетом – alhazen

2

Это было бы намного проще в .NET 4.0 с помощью Task Parallel Library.

Когда вы планируете обновить? Это может быть скорее, чем вы сами могли бы написать весь необходимый координирующий код.

Если вам нужно выполнить эту грубую силу, вы можете использовать Thread.BeginThreadAffinity, чтобы обеспечить выполнение прилагаемого кода на одном CPU. Это должно помочь вам выполнить расчет.

0

Как уже упоминалось в комментариях, PLINQ делает это очень просто.

List<Calculation> foo = ...; 
foo.AsParallel.Select(c => c.Calculate()); 
+0

Но предполагается, что нет никаких зависимостей между объектами Calculation? – alhazen

+1

Это использует .Net 4, если я не ошибаюсь –

+0

@steve townsend, да, это зависит от версии 4.0 фреймворка ... если это проблема, вам придется управлять своими потоками, как и другие сообщения. – tbischel