Соотношение между ядрами и количеством потоков, которые я могу создать

2

У меня есть процессор Intel Quad Core.

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

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

  • 0
    Сколько потоков вы хотите создать? Если вы вообще обеспокоены каким-либо ограничением, у вас, вероятно, слишком много.
  • 0
    Я не породил ни одного. Это гипотетически и на будущее (я довольно любопытный и любознательный, и многие вопросы, которые я задаю, не имеют отношения к какой-либо текущей разработке, которую я делаю). Я хочу знать теорию.
Теги:
multithreading
concurrency
hardware

5 ответов

11

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

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

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

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

  • Измерение меры измерения.

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

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

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

0

Просто подумал, какой предел будет поражен первым, начав много потоков. Я написал следующую простую тестовую программу и попробовал ее. Теперь я предполагаю, что память является ограничивающим фактором. Я смог запустить 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);
            }
        }
    }
}
0

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

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

Ограничения на потоки (в Windows), о которых я знаю, следующие:

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

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

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

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

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

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

0

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню