2015-01-29 1 views
2

Два из наиболее распространенных по умолчанию, которые я видел, когда проклейки неблокируемому пула потоков являются:Java номер оптимально по умолчанию потоков без блокировки ввода/вывода

number of threads = number of cores 

number of threads = number of cores + 1 

, но теперь я нашел еще один в Vert.x , который:

number of threads = 2 * number of cores 

Видимо logic behind this value, что, как Java не имеет никакого способа закрепления конкретного потока для конкретного ядра, если мы устанавливаем # threads == # cores, мы могли бы тратить некоторые из доступных ядер. Теоретически, установив # threads на что-то вроде 2 * # cores, вероятность использования всех ядер увеличивается.

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

Я знаю, что все это зависит от вида выполняемых операций, но, при условии, что нет блокировки ввода-вывода (поэтому нет необходимости иметь неактивные потоки, ожидающие много времени для ресурса), является 2 * # cores лучшим подхода по умолчанию, чем # cores ? Зачем?

+0

Я подозреваю, что у них включена гиперпоточность, которая позволяет одновременно запускать два потока на каждое ядро. –

+0

Тогда возникает вопрос, сколько ядер действительно есть? http://www.javaspecialists.eu/archive/Issue220.html – edharned

ответ

2

Окончательная книга для Java потоков (Java Параллелизм на практике) говорит:

Для ресурсоемких задач, система Ncpu-процессор обычно достигает оптимального использования с резьбовым пула Ncpu +1 потоков. (Даже с интенсивными вычислениями нити иногда принимает страничную ошибку или приостановить какую-то другую причину, так что «лишний» работоспособный поток предотвращает циклы CPU от перехода неиспользованным, когда это случается.)

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

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

+0

Re: «... даже если не было ввода-вывода». В параграфе, который вы цитировали, говорится вам, что там _is_ I/O, даже если там «нет ввода-вывода». Пейджинг - это ввод-вывод. –

+0

@jameslarge Да. Я имел в виду, что в коде не было явного ввода-вывода. – lbalazscs

2

Единственный окончательный ответ на профиль каждого из них, потому что поведение зависит от того, что работает на целевой системе, а также код вовлеченного.

Если все потоки получают равное время, наличие (2 * сердечников) вызовет больше переключателей контекста, которые могут нанести штраф.

Также незначительно связано, - это библиотека сродства потоков для Java под названием OpenHFT - которая использует собственный код - позволяет связывать потоки с конкретными ядрами.