2009-02-11 4 views
3

Можете ли вы сделать копирование файлов быстрее с помощью нескольких потоков?Оптимизация копирования файлов с помощью нескольких потоков

Редактировать: Чтобы уточнить, предположим, что вы использовали CopyFile (src, tgt). Кажется логичным, что при определенных обстоятельствах вы можете использовать несколько потоков, чтобы ускорить работу.

Редактировать еще несколько мыслей:

Естественно, это зависит от HW/хранения в вопросе.

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

Но если async-IO может реально ускорить работу (до 2x) при чтении/записи с разных дисков, почему это не стандартная реализация CopyFile? (или это?)

+0

Вы говорите об одном файле с потоками? Или несколько файлов с потоками? – JFV

ответ

2

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

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

Что касается дополнительного вопроса вы добавили:

Но если асинхронной-IO действительно может ускорить вещи (до 2x) при чтения/записи с разных дисков, почему не это по умолчанию реализация CopyFile? (Или это?)

Я не знаю, внутренности CopyFile(), но я не удивлюсь, если они не делают это по нескольким причинам:

  1. если бы они были для реализации его с использованием дополнительного потока (или потоков), который может быть немного более навязчивым для процесса, чем это уместно (особенно если процесс является одним потоком до этой точки)
  2. , если они попытались реализовать его с использованием асинхронного I/O с одной нитью (как вариант ChrisW indicated), они могут быть скорее вероятны как проблемы с улучшением производительности.В общем случае нелегко будет определить, когда вы получите выгоду, а не ущерб.

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

+0

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

4

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

+0

@ocdecio: Кроме того, не забывайте об ограничениях сетевой карты, ЦП и ОЗУ. Если вы копируете несколько файлов одновременно в разных потоках, вам также необходимо учитывать эти соображения. – JFV

+0

@JFV - Правильно. Единственный раз, когда я видел хорошее использование для нескольких потоков, было сканирование каталогов в параллельном режиме. –

+0

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

2

я думаю нет. Для процессора так мало.

+0

Правда, но вы не могли бы извлечь выгоду из чтения/записи в одно и то же время, например? Или от чтения и записи в разных местах в одном и том же (в некоторых решениях для хранения)? –

+0

Но процессор не выполняет всю эту работу для этих целей. Disk IO делает. – sblundy

+0

@sblundy - но у вас есть потенциал для одновременного хранения разных аппаратных компонентов. –

1

Это зависит, но, как правило, нет, ваше узкое место будет дисковым IO, и вы не сможете быстрее сделать IO с помощью нескольких потоков.

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

+0

, даже если вы читаете/записываете отдельные диски? –

1

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

Для улучшения производительности он может быть полностью реализован в ядре.

+0

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

+0

Нет, это похоже на «начинать чтение, начинать запись, блокировать до тех пор, пока не завершится ... когда один (чтение или запись) завершается, а затем запускает асинхронный другой (который принимает незначительное время для начала), а затем возвращается в ожидании следующего завершения ». – ChrisW

3

Вот блоге о улучшения производительности копирования файлов в Vista SP1:

http://blogs.technet.com/markrussinovich/archive/2008/02/04/2826167.aspx

Doing высокой производительности копирования файлов с ума, и вы должны принять во внимание такие вещи, как поведение кэша и ограничения сетевых драйверов.

Так что всегда используйте функцию копирования файлов ОС (под Windows это FileCopyEx) и не пишите свои собственные.

Смежные вопросы