Какова связь между количеством ядер процессора и количеством потоков в приложении в java?

Я новичок в java многопоточном программировании. Вопрос, который пришел мне на ум, заключается в том, сколько потоков я могу запустить в соответствии с количеством моих ядер процессора. и если я запускаю потоки больше, чем ядра процессора, это будет накладные расходы для запуска этого приложения. например, когда у нас есть серверная машина, у которой есть серверное программное обеспечение, которое запускает 2 потока (основной поток + поток разработчиков), будет ли это накладными для сервера, когда более одновременные клиенты делают подключения сокетов к серверу или нет?

Спасибо.

Ответ 1

Количество потоков, которые система может выполнять одновременно (конечно), идентично количеству ядер в системе.

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

Обычно сегодняшние компьютеры могут обрабатывать сотни-тысячи потоков.

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

Ответ 2

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

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

Ответ 3

Не беспокойтесь о получении большего количества потоков, чем ядра ЦП; это на самом деле не в ваших руках, а в ОС.

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

Что вы должны иметь в виду, так это то, что ваш дизайн должен быть устойчивым. Например, серверы приложений построены на потоке, заполненном рабочими потоками. Эти потоки пробуждаются, чтобы обслуживать запросы. Вы хотите поток для каждого запроса? Тогда у вас наверняка возникнет проблема: запросы могут поступать в тысячи на сервер, и это может быть проблемой для управления ядром. Фактически размер threadpool должен быть ограничен (между 1 и X и легко изменяется даже в реальном времени), потоки должны получать работу из параллельной очереди (java дает вам отличные классы для этого), и каждый из них посещает запросы последовательно.

Я надеюсь, что помощь

Ответ 4

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

Полезно проверить Настройка размера пула, в документе IBMs

Идея заключается в том, что она зависит от характера задачи, если все ее задачи вычисления в памяти можно использовать N + 1 потоков (N чисел ядер (включая гиперпоточность)).

Или

нам нужно выполнить профилирование приложений и узнать время ожидания (WT), время обслуживания (ST) для типичного запроса и приблизительно N * (1 + WT/ST) количество оптимальных потоков, которые мы можем иметь, учитывая 100% использование CPU.

Ответ 5

Имея меньше потоков, чем процессоры, вы можете не использовать все процессоры в вашей системе. Наличие большего количества потоков может повысить пропускную способность, если CPU является вашим узким местом.

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

Ответ 6

Наилучшая производительность будет, когда количество ядер (NOC) равно числу потоков ( НЕ), потому что если NOT > NOC, то процессор должен переключить контекст или ОС попытается выполнить эту работу, что достаточно дорогостоящее. Но вы должны понять, что невозможно иметь NOC = NOT на веб-серверах, потому что вы не можете предсказать, сколько клиентов будет одновременно. Взгляните на балансировку нагрузки, чтобы наилучшим образом решить эту проблему.

Ответ 7

Там не должно быть никакого отношения. Компьютер может иметь любое количество ядер; процесс может иметь любое количество потоков.

Существует несколько различных причин, по которым процессы используют многопоточность, в том числе:

  • Программирование абстракции. Разделение работы и назначение каждого подразделения на единицу исполнения (поток) является естественным подходом ко многим проблемам. Шаблоны программирования, использующие этот подход, включают шаблоны реактора, потока на соединение и пула потоков. Некоторые, однако, рассматривают темы как анти-шаблон. Неподражаемый Алан Кокс хорошо подвел итог этой цитате: "Темы предназначены для людей, которые не могут программировать конечные автоматы".

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

  • Экономия памяти. Потоки обеспечивают эффективный способ совместного использования памяти, но используют несколько единиц выполнения. Таким образом, они являются альтернативой нескольким процессам.

  • Параллельность. В машинах с несколькими процессорами потоки обеспечивают эффективный способ достижения истинного параллелизма. Поскольку каждый поток получает свой собственный виртуализированный процессор и является независимо планируемым объектом, несколько потоков могут работать на нескольких процессорах одновременно, что повышает пропускную способность системы. В той степени, в которой потоки используются для достижения параллелизма, то есть потоков больше, чем процессоров, цитата "потоки для людей, которые не могут программировать конечные автоматы" не применяется.

Первые три пули используют нити, не связанные с ядрами. Например, если вы используете потоки в качестве программной абстракции для обработки элементов пользовательского интерфейса, у вас будет один поток на элемент пользовательского интерфейса (или любой другой) независимо от того, есть ли у вас 1 ядро или 12. Аналогично, если вы использовали потоки для выполнения блокировки Ввод/вывод, вы будете масштабировать количество потоков в соответствии с пропускной способностью ввода/вывода, а не с вычислительной мощностью.

Четвертая пуля, однако, касается нитей с сердечниками. Если целью многопоточности является параллелизм, то число потоков должно масштабироваться линейно с количеством ядер. Например, если вы удвоите число ядер в системе, то вы удвоите количество потоков в своем приложении. Это верно для ядер в логическом смысле, то есть для SMT.

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