Java: я хочу настроить размер пула потоков. Как я могу определить начало сбора данных CMS или другие общесистемные факторы, влияющие на доступный ЦП?

(Специфика этого вопроса касается мода для Minecraft. В общем, вопрос касается изменения размера пула потоков в зависимости от загрузки системы и доступности ЦП).

Я исхожу из фона Objective C и Apple libdispatch (Grand Central Dispatch) для планирования потоков.

Непосредственное беспокойство у меня вызывает попытка уменьшить размер пула потоков, когда запущена временная коллекция CMS. Рассматриваемая программа (Minecraft) хорошо работает только с коллекциями CMS. Гораздо менее актуальным, но все же «интересным» является уменьшение размера пула потоков, когда другие программы требуют значительных ресурсов ЦП (в частности, либо устройство записи экрана, либо поток twitch).

В Java я только что узнал о (глубокий вдох):
Executors, которые предоставляют доступ к пулам потоков (как фиксированного, так и регулируемого размера), с существованием кэшированных потоков (чтобы избежать накладных расходов, связанных с постоянным воссозданием новых потоков, или чтобы не беспокоиться о кодировании потоков для приостановки и возобновления в зависимости от рабочей нагрузки),
Executor (no s), который является универсальным интерфейсом для сообщения «Теперь пора выполнить this runnable ()»,
ExecutorService, который управляет пулами потоков в соответствии с Executor,
ThreadPoolExecutor, который фактически управляет пулом потоков, и имеет возможность сказать «Это максимальное количество потоков для использования».

При нормальной работе, примерно 5 раз в секунду, будет 50 операций с высоким приоритетом и 400 операций с низким приоритетом, отправляемых в пул потоков для каждого пользователя на сервере. Это для мощных машин.

Что я хочу сделать:

  1. Работайте с менее мощными машинами. Итак, если у компьютера всего 2 ядра, а основная программа (два основных потока плюс несколько второстепенных вспомогательных потоков) уже загружает ЦП на максимум, эти фоновые задачи будут конкурировать с основной программой и сборщиком мусора. В этом случае я не хочу уменьшать количество фоновых потоков (оно, вероятно, останется на уровне 2), но я хочу уменьшить объем запланированной работы. Итак, это просто «Как мне определить, когда рабочая нагрузка возрастает». Я подозреваю, что это всего лишь случай наблюдения за размером рабочей очереди, которую я использую, когда Executors.newCachedThreadPool ()

Но первая проблема: не могу найти ничего, чтобы вернуть размер очереди работ! ThreadPoolExecutor () может возвращать очередь, и я могу запросить это для размера, но newCachedThreadPool () возвращает только ExecutorService, который не позволяет мне запрашивать размер (или, скорее, я не знаю, как это сделать).

  1. Если у меня «достаточно ядер», я хочу сказать пулу использовать больше потоков. В идеале достаточно, чтобы загрузка ЦП была близка к макс. Большинство задач, которые я хочу выполнить, связаны с процессором (дисковый ввод-вывод будет исключением, а не правилом; блокировка параллелизма также будет редкостью). Но я не хочу сильно перегружать потоки. Как определить «достаточное количество потоков», не перебирая доступные ядра?

  2. Если, например, активируется запись экрана (или потоковая передача), загрузка ядра ЦП другими программами возрастет, и тогда я хочу уменьшить количество потоков; по мере того, как количество потоков уменьшается, а объем невыполненной работы очереди увеличивается, я могу уменьшить количество задач, которые я добавляю в очередь. Но я понятия не имею, как это обнаружить.


person Keybounce    schedule 04.10.2015    source источник


Ответы (1)


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

Для потоковой передачи «в реальном времени» ваш успех будет зависеть от общей нагрузки и способности планировщика расставлять приоритеты больше, чем количество потоков. Однако факт, что стандартная Java SE в стандартной ОС не подходит для жесткого реального времени, поэтому ваша производительность в реальном времени может сильно ухудшиться, если вы выйдете за рамки.

person Stephen C    schedule 04.10.2015
comment
Это ... не совсем тот ответ, который я хотел :). Я определенно хочу использовать как можно больше свободного ЦП; то, что я хочу запустить, обычно будет зависеть от ЦП, за исключением того, что я понял, что у меня ужасная проблема с обеденными философами, которая вызовет у меня проблемы с блокировкой. И простой подход к этому оставит процессор простаивающим. - person Keybounce; 07.10.2015
comment
Извините, позвольте мне попробовать еще раз. Это не в реальном времени. Это больше похоже на доступное время. Надо будет поработать, даже если это замедлит игру. Будет некоторая работа, которая, насколько позволяет доступный ЦП, должна рассматриваться как задание с очень низким приоритетом - не мешайте ничему другому работающему, но делайте это, если есть свободный ЦП. Фиксированное количество потоков: проблема в том, что оно может меняться. Если в системе больше ничего не работает, то есть разумное количество потоков для использования, которое будет зависеть от компьютера. Но все меняется. Передвижение в игре и т. Д. - person Keybounce; 07.10.2015
comment
Лучший способ решить вашу (переформулированную) проблему - использовать приоритеты потоков. Регулировать размеры пула потоков слишком сложно. Я серьезно сомневаюсь, что вы вообще можете заставить динамический размер пула работать ... не говоря уже о том, чтобы он в достаточной мере отвечал вашим потребностям. - person Stephen C; 07.10.2015
comment
Что касается вашей проблемы обедающих философов, существуют известные стратегии для избежания или обнаружения / выхода из тупиков. Вам не нужно использовать простаивающие процессоры, чтобы решить эту проблему, - person Stephen C; 07.10.2015
comment
Стратегии, которые я видел для выхода из тупика Dining Philosopher, требуют либо некоторого общения / официанта, либо какого-то типа того, что я снимаю блокировки, засыпаю на некоторое время и пытаюсь снова. Переход в спящий режим подразумевает потраченное впустую ЦП / простаивающие ядра. Хуже того (ключевой момент этой проблемы блокировки), поскольку основной поток игрового сервера не имеет концепций синхронизации, даже если я могу заставить его ждать этих фоновых вычислений, он может спать дольше, чем приемлемый ответ игрока. - person Keybounce; 07.10.2015
comment
(грр, абзацы добавлять нельзя). Что касается приоритетов потоков: я о них раньше не знал. Прочитав о них, я остаюсь с необходимостью их использования, которая подразумевает более серьезную проблему, поскольку нет никакой гарантии относительно того, что они делают. В частности, они будут вести себя по-другому в Linux / Mac OS / Microsoft Windows. Итак, не лучшая идея. - person Keybounce; 07.10.2015
comment
Не стесняйтесь игнорировать мой совет :-) - person Stephen C; 08.10.2015
comment
Извини, я не хочу тебя игнорировать. Даже без микроуправления размером пула потоков и желания позволить некоторым простаивающим процессорам не использоваться: приоритеты потоков, потому что они имеют разные функции в разных ОС, а на некоторых ОС действуют как голодание, а на других действуют как уменьшенные, но все же гарантированные беги, они просто не справляются со своей работой. Они не могут быть решением, потому что у них нет надежного поведения. (Репутация 320K выдается не просто так; вы помогли другим и знаете, о чем говорите. Я думаю, что это просто редкая оплошность.) @Stephen c - person Keybounce; 10.10.2015