Каково оптимальное количество потоков для выполнения операций ввода-вывода в Java? - PullRequest
16 голосов
/ 06 августа 2009

В «Практике Java-параллелизма Гетца» в сноске на стр. 101 он пишет «Для таких вычислительных задач, которые не требуют ввода-вывода и доступа к общим данным, потоки Ncpu или Ncpu + 1 обеспечивают оптимальную пропускную способность; потоки не помогают, и могут фактически ухудшить производительность ... "

Мой вопрос: при выполнении операций ввода-вывода, таких как запись файла, чтение файла, удаление файла и т. Д., Существуют ли рекомендации по количеству потоков, используемых для достижения максимальной производительности? Я понимаю, что это будет просто ориентировочное число, поскольку скорость диска и множество других факторов играют в этом роль.

Тем не менее, мне интересно: могут ли 20 потоков записать 1000 отдельных файлов на диск быстрее, чем 4 потока на машине с 4 процессорами?

Ответы [ 7 ]

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

На практике приложения, связанные с вводом / выводом, все еще могут существенно выиграть от многопоточности, поскольку они могут намного быстрее читать или записывать несколько файлов параллельно, чем последовательно. Это в особенности тот случай, когда общая пропускная способность снижается из-за задержки в сети. Но это также тот случай, когда один поток может обрабатывать последнее, что он прочитал, в то время как другой поток занят чтением, что позволяет увеличить загрузку ЦП.

Мы можем говорить о теории весь день, но правильный ответ - сделать количество потоков настраиваемым. Я думаю, вы обнаружите, что увеличение его после 1 повысит вашу скорость, но также наступит момент уменьшения отдачи.

4 голосов
/ 06 августа 2009

Да, 20 потоков могут определенно записывать на диск быстрее, чем 4 потока на 4-процессорной машине. Многие реальные программы связаны с вводом / выводом больше, чем с процессором. Тем не менее, это очень подробно зависит от ваших дисков и от того, сколько ЦП работает с другими вашими потоками, прежде чем они тоже будут ждать этих дисков.

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

Преимущество многопоточности намного проще, когда вы подключены к сети. То есть: ожидание на сервере базы данных, или веб-браузер, или тому подобное. Там вас ждут несколько внешних ресурсов.

3 голосов
/ 07 августа 2009
3 голосов
/ 06 августа 2009

Как и все, что связано с производительностью, это зависит.

Если вы связаны с вводом / выводом, то добавление потоков вам совсем не поможет. (Хорошо, как указывает Стивен Судит , вы можете увеличить производительность, но она будет небольшой) Если вы не привязаны к вводу / выводу, добавление потоков может помочь

Не пытайтесь быть умным, но лучший способ выяснить это - профилировать его и посмотреть, что подходит для ваших конкретных обстоятельств.

Редактировать: Обновлено на основе комментариев

2 голосов
/ 06 августа 2009

Если вы используете синхронный ввод / вывод, то у вас должен быть один поток для каждого одновременного запроса ввода / вывода, который может обработать ваша машина. В случае одного жесткого диска с одним шпинделем это 1 (вы можете либо читать, либо записывать, но не оба одновременно). Для диска, который может обрабатывать много запросов ввода-вывода одновременно, это будет, однако, много запросов, которые он может обрабатывать одновременно.

Другими словами, это не ограничено подсчетом ЦП, поскольку ввод-вывод на самом деле не затрагивает ЦП, кроме отправки запросов и ожидания. Смотрите здесь для лучшего объяснения.

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

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

Ncpu + ожидаемое количество одновременных операций ввода-вывода - мой обычный номер.

Ключ не в том, что 20 потоков могут записать один файл на диск быстрее, чем 4 потока. Если у вас есть только один поток на процессор, то во время записи на диск ваш процесс не сможет использовать процессор, на котором размещен поток, выполняющий ввод-вывод файла. Этот ЦП фактически ожидает записи файла, тогда как если у вас есть еще один поток, он может использовать ЦП для реальной обработки в промежуточный период.

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...