Сколько потоков для чтения и записи на жесткий диск?
Я занимаюсь разработкой приложения, которое собирает список со всеми файлами жесткого диска, а также после этого записывает файлы на жесткий диск.
Я хочу спросить: каково оптимальное количество одновременных потоков, которые будут выполнять эту задачу?
Я имею в виду, сколько потоков должно иметь это чтение жесткого диска без замедления жесткого диска, потому что многие потоки читают его одновременно.
Спасибо!
7 ответов
Сначала я говорю один!
Это на самом деле зависит от того, нужны ли для чтения данные для сложных вычислений. В этом случае может быть удобно создать более одного потока для обработки различных данных на диске; но это удобно, только если у вас несколько процессоров в одной системе.
В противном случае более чем один поток делает жесткий диск более напряженным, чем необходимо: одновременное чтение из разных потоков вызовет операции поиска для чтения файловых блоков (*), что приводит к дополнительным издержкам, которые могут замедлить работу системы, в зависимости от количества прочитанных файлов и размер файлов.
Читайте файлы последовательно.
(*) ОС действительно пытается последовательно хранить одни и те же файловые блоки, чтобы ускорить операции чтения. Происходит фрагментация диска, поэтому непоследовательные фрагменты требуют операции поиска, которая требует действительно большего времени для операции чтения в том же месте. Попытка чтения нескольких файлов параллельно вызовет кучу запросов, потому что блоки одного файла являются смежными, а блоки нескольких файлов могут быть не смежными.
Одна нить. Если вы читаете и пишете одновременно, и вашим местом назначения является диск, отличный от вашего источника, тогда 2 потока. Я добавлю, что если вы выполняете другие операции с файлами (например, распаковка), то распаковка может быть выполнена в третьем потоке.
Чтобы привести несколько примеров (я игнорирую соединения, точки повторной обработки...)
- C: to C: 1 Тема ВСЕГО
- C: to D: один и тот же физический диск, разные разделы: 1 поток ВСЕГО
- C: D: другой физический диск: 2 темы ВСЕГО
Я работаю на предположении, что диск может выполнять ОДНУ операцию за раз, и каждый раз, когда он "многозадачен", переключаясь между различными операциями чтения / записи, он теряет в скорости. Механические диски имеют эту проблему (но технически NCQ МОЖЕТ помочь). Твердотельные диски, которых я не знаю (но я знаю, что USB-флешки ОЧЕНЬ медленны, если вы пытаетесь сделать 2 операции одновременно)
Я искал, как вы это делаете... Я не нашел никаких "конкретных" примеров, но у меня есть несколько ссылок на Windows API, с которых вы могли бы начать:
Отображение путей к томам: http://msdn.microsoft.com/en-us/library/cc542456%28VS.85%29.aspx
GetVolumePathName: http://msdn.microsoft.com/en-us/library/aa364996(v=VS.85).aspx
GetVolumeInformationByHandleW http://msdn.microsoft.com/en-us/library/aa964920(v=VS.85).aspx
Никогда не обрабатывайте IO-плотные операции одновременно. Это медленнее, потому что зонд диска тратит много времени на переключение между различными потоками / файлами.
Что мне делать, если у меня есть несколько потоков в операциях ввода-вывода? Производите операции одновременно и выполняйте их однопоточно. У нас есть контейнер, как ConcurrentQueue<T>
(или потокобезопасная очередь, написанная вами), и есть 10 потоков, которые будут читать из этих файлов 1.txt 2.txt ... 10.txt. Вы помещаете "запросы на чтение" в очередь одновременно, другой поток обрабатывает все запросы (откройте 1.txt, получите то, что вы хотите и продолжите с 2.txt), дисковый зонд не будет занят переключением между потоками / файлы в этом случае.
Как следует из тега "C#", я предполагаю, что вы пишете управляемое приложение для выполнения дискового ввода-вывода.
В этом случае, я предполагаю, что число управляемых потоков на уровне пользователя не имеет значения, поскольку они не являются теми, которые фактически выполняют дисковый ввод-вывод.
Насколько я знаю, запросы дискового ввода-вывода от управляемых потоков уровня пользователя будут поставлены в очередь в очереди APC уровня ядра, и потоки ввода-вывода Windows будут обрабатывать их.
Таким образом, я бы сказал, что частота запросов дискового ввода-вывода, которые должны быть поставлены в очередь в очереди APC, будет в большей степени соответствовать вашему вопросу.
Я не видел ни одного API-интерфейса.NET, позволяющего связывать любые пользовательские задачи с потоками ввода-вывода Windows. Тем не менее, обратите внимание, что мой ответ основан на относительно старой информации в следующей ссылке Потоки ввода-вывода Windows и потоки управляемого ввода-вывода.
Если кто-то лучше знает текущую модель пула потоков Windows 7, которая отличается от информации, приведенной в ссылке, пожалуйста, поделитесь этой информацией, чтобы обучить меня.
Кроме того, вы можете найти следующую ссылку полезной для понимания операций ввода-вывода файла Windows: Синхронный и Асинхронный ввод-вывод
Многие ответы относятся к количеству жестких дисков. Имейте в виду, что это также зависит от количества контроллеров. Иногда два жестких диска управляются одним контроллером. Также: два раздела на одном и том же HDD - это не два HDD!
Если он выходит с одного жесткого диска, то вы хотите минимизировать время поиска. Поэтому используйте только один поток для чтения и записи на диск.
Я бы сказал, что одной нити достаточно. Процессор может запускать много потоков, но скорость жесткого диска на много порядков ниже скорости процессора. Даже если запуск большего количества потоков сделает запросы на ввод / вывод быстрее (в этом я не уверен), это не заставит жесткий диск фактически читать быстрее. Это может даже замедлить его.