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

У меня есть четырехъядерный процессор Intel.

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

Существует ли какая-то корреляция между ядрами и максимальным количеством потоков, которые я могу запустить в любое время? Нужно ли мне узнать, сколько потоков запущено одновременно, и если да, возможно ли это? (Я знаю, что есть свойства, такие как минимальные и максимальные потоки)? Зависит ли это от пула потоков (меняется ли максимальное количество потоков в этом пуле?). Это часть C # этого поста / темы.

Ответы [ 5 ]

11 голосов
/ 04 августа 2009

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

.Нет потока резьбы имеет: http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx

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

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

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

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

1 голос
/ 04 августа 2009

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

0 голосов
/ 04 августа 2009

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

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

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

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

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

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

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

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

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

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

0 голосов
/ 04 августа 2009

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

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

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

...