2009-08-03 4 views
2

У меня есть процессор Intel Quad Core.Связь между ядрами и числом потоков, которые я могу создать

Если бы я должен был разработать приложение Winforms, которое будет использоваться только на моей машине (я использую C# btw), сколько потоков я могу создать?

Есть ли какая-то корреляция между ядрами и максимальным количеством потоков, которые я могу запустить в любой момент? Должен ли я узнать, сколько потоков работает в любой момент, и если да, возможно ли это? (Я знаю, что есть такие свойства, как min и max threads)? Будет ли это зависеть от threadpool (изменяется ли max нитей в этом пуле?). Это часть C# этого сообщения/потока.

+0

Сколько потоков вы ищете для появления? Если вас вообще интересуют какие-либо ограничения, вы, вероятно, слишком много. –

+0

Я никого не породил. Это гипотетично и для будущего (мне очень любопытно и любознательно, и многие вопросы, которые я задаю, не связаны с каким-либо текущим развитием, которое я делаю). Я хочу знать теорию. – dotnetdev

ответ

11

Это все зависит от, если ваши потоки активны (и не ждут ввода-вывода) в 100% случаев, тогда есть немного смысла в том, чтобы иметь больше 1 потока на процессор. Однако это редко бывает, если вы не выполняете сложные числовые вычисления.

.Nets ThreadPool имеет: http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx

пул потоков имеет размер по умолчанию 250 рабочих потоков на имеющихся процессора и 1000 завершения ввода/вывода нитей.

Так что, я бы сказал, есть очень мало рекомендаций кто может дать вам, кроме того:

  • Мера мера мера.

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

+1

+1 Нахождение сладкого пятна с нитями должно быть одной из самых простых задач профилирования. вам нужно всего лишь пробовать около 20 точек данных на большинстве потребительских машин, чтобы увидеть довольно очевидную тенденцию, обычно 10 достаточно. Поскольку это число будет * полностью * dpend на то, что делают потоки, и спецификации всех компонентов системы, это действительно единственный способ. – ShuggyCoUk

0

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

Что касается количества потоков, которые вы можете создать, это зависит от системы. Класс ThreadPool не устанавливает ограничений на создание собственных потоков; у него есть, ну, пул нитей, которые он сам управляет собой. Таковы значения, которые вы можете увидеть при проверке свойств класса ThreadPool. Это, однако, не означает, что вы должны создавать бесконечные потоки; в конечном итоге ОС будет тратить больше времени на переключение между вашими потоками, чем будет тратить фактически, чтобы ваши потоки выполнялись. Выясните, сколько потоков подходит для вашего приложения посредством бенчмаркинга.

Что именно вы пытаетесь сделать?

0

Сколько потоков я могу создать?

Waaay, waaay больше (сотни или тысячи раз), чем вы хотели бы создать для оптимальной пропускной способности.

Ограничения Межпоточное (на Windows), я в курсе являются:

  • 16-битный идентификатор потока
  • 4-8KB распределение для пользовательского пространства стека (обычно, намного больше)
  • Non-выгружаемой контекст ядра пространство стека и что-то вроде 16KB

Dotnet вероятно добавляет кучу накладных каждой нити для своего собственного материала. GC и тому подобное.

Одна формула Я хотел использовать для WAG является:

threads = 2 * (cpu cores + active disk spindles) 

Оптимальное количество, как правило, в пределах фактора двух из этого. того, что. Теория состоит в том, что необходимые потоки proprotional для ядер процессора (по очевидным причинам), но также и то, что некоторые потоки будут блокировать диск ввода-вывода. Умножение на два дает CPU что-то делать, пока другие потоки блокируются.

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

0

Просто интересно, какой предел будет поражен первым, начав много потоков. Я написал следующую простую тестовую программу и попробовал ее. Теперь я предполагаю, что память является ограничивающим фактором. Я смог запустить 1000 потоков, но без Thread.Sleep() система стала «немного не реагировать». С потоками 2000 я получил исключение из памяти после запуска около 1800 потоков. (Ноутбук с процессором Intel Core 2 Duo T5800 2,0 ГГц, 3,0 Гигабайт RAM и "несколько" приложений, работающих на Windows XP SP3 с .NET Framework 3.5 SP1)

UPDATE

Выездное исключения памяти является вызванный стеком потоков. После определения размера стека в конструкторе потока (я использовал 64 кбайт, но, вероятно, минимальный размер, который я не знаю в данный момент), я смог запустить 3500 потоков (с Thread.Sleep()).

using System; 
using System.Linq; 
using System.Threading; 

namespace GeneralTestApplication 
{ 
    class Program 
    { 
     private static void Main() 
     { 
      Console.WriteLine("Enter the number of threads to start."); 

      while (!Int32.TryParse(Console.ReadLine(), out Program.numberThreads)) { } 

      Program.counters = new Int64[Program.numberThreads]; 

      Console.WriteLine("Starting {0} threads.", Program.numberThreads); 

      for (Int32 threadNumber = 0; threadNumber < Program.numberThreads; threadNumber++) 
      { 
       new Thread(Program.ThreadMethod).Start(threadNumber); 
      } 

      Console.WriteLine("Press enter to perform work on all threads."); 
      Console.ReadLine(); 

      Program.manualResetEvent.Set(); 

      Console.WriteLine("Press enter to stop all threads."); 
      Console.ReadLine(); 

      Program.stop = true; 

      Console.WriteLine("At least {0} threads ran.", Program.counters.Count(c => c > 0)); 

      Console.ReadLine(); 
     } 

     private static Int32 numberThreads = 0; 
     private static Int64[] counters = null; 
     private static readonly ManualResetEvent manualResetEvent = new ManualResetEvent(false); 
     private static volatile Boolean stop = false; 

     public static void ThreadMethod(Object argument) 
     { 
      Int32 threadNumber = (Int32)argument; 

      Program.manualResetEvent.WaitOne(); 

      while (!Program.stop) 
      { 
       Program.counters[threadNumber]++; 

       // Uncomment to simulate heavy work. 
       Thread.Sleep(10); 
      } 
     } 
    } 
} 
1

Вы должны измерить. Таким образом, с ядром N Я обычно получаю наилучшие результаты, создавая нерестилища между N + 1 и 2N темы. Но вы должны измерить.

Смежные вопросы