У меня есть процессор Intel Quad Core.
Если бы я должен был разработать приложение Winforms, которое будет использоваться только на моей машине (я использую С# btw), сколько потоков я могу создать?
Есть ли какая-то корреляция между ядрами и максимальное количество потоков, которые я могу запустить в любой момент? Должен ли я узнать, сколько потоков работает в любой момент, и если да, возможно ли это? (Я знаю такие свойства, как min и max threads)? Будет ли это зависеть от threadpool (изменяется ли max нитей в этом пуле?). Это часть С# этого сообщения/потока.
Все зависит, если ваши потоки активны (и не ждут ввода-вывода) в 100% случаев, тогда мало смысла иметь больше одного потока на процессор. Однако это редко бывает, если вы не выполняете сложные числовые вычисления.
.Nets threadpool имеет: http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx
Пул потоков имеет размер по умолчанию 250 рабочих потоков за каждый доступный процессор и 1000 операций ввода/вывода потоки.
Итак, я бы сказал, есть очень мало рекомендаций, которые могут вам дать, кроме того:
В какой-то момент, когда вы добавляете больше потоков , материал будет медленнее, из-за переключения контекста и синхронизации.
Вам нужно измерить. Тем не менее, с N ядрами я обычно получаю наилучшие результаты за счет нереста между N + 1 и 2N потоками. Но вы должны измерить.
Просто подумал, какой предел будет поражен первым, начав много потоков. Я написал следующую простую тестовую программу и попробовал ее. Теперь я предполагаю, что память является ограничивающим фактором. Я смог запустить 1000 потоков, но без Thread.Sleep()
система стала "немного не реагировать". С потоками 2000 я получил исключение из памяти после запуска около 1800 потоков. (Ноутбук с процессором Intel Core 2 Duo T5800 с тактовой частотой 2,0 ГГц, 3,0 ГБ и "несколькими" приложениями, работающими на 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);
}
}
}
}
сколько потоков я могу создать?
Waaay, waaay больше (сотни или тысячи раз), чем вы хотели бы создать для оптимальной пропускной способности.
Ограничения на потоки (в Windows), о которых я знаю, следующие:
Dotnet, вероятно, добавляет кучу накладных расходов для каждого потока. GC и т.п.
Одна формула, которую мне нравится использовать для WAG:
threads = 2 * (cpu cores + active disk spindles)
Оптимальное число обычно находится в два раза. того, что. Теория состоит в том, что необходимые потоки proprotional для ядер процессора (по очевидным причинам), но также и то, что некоторые потоки будут блокировать диск ввода-вывода. Умножение на два дает процессору что-то делать, а другие потоки блокируются.
В любом случае, начните с этого и измерьте его. Количество рабочих потоков - это самая легкая часть всей проблемы, которую нужно настроить позже, поэтому не беспокойтесь об этом сейчас.
Пока существует некоторая корреляция между потоками и ядрами (единственный способ для потоков, выполняемых по-настоящему одновременно, будет заключаться в том, чтобы они запускались на отдельных ядрах, но это знание имеет меньшую ценность, чем вы могли бы подумать), настоящая работа сделанный планировщиком операционной системы, в этом случае планировщик потоков в Windows.
Что касается количества потоков, которые вы можете создать, это зависит от системы и системы. Класс ThreadPool
не устанавливает никаких ограничений на создание собственных потоков; у него есть, ну, пул нитей, которые он сам управляет собой. Таковы значения, которые вы можете увидеть при проверке свойств класса ThreadPool
. Это, однако, не означает, что вы должны создавать бесконечные потоки; в конечном итоге ОС будет тратить больше времени на переключение между вашими потоками, чем будет тратить фактически, чтобы ваши потоки выполнялись. Выясните, сколько потоков подходит для вашего приложения посредством бенчмаркинга.
Что именно вы пытаетесь сделать?