2012-01-16 2 views
8

Я нахожусь перед куском кода, который копирует файл на USB-устройство. После части является важным:Выполнение копирования файла с fread/fwrite на USB

while((bytesRead = fread(buf, 1, 16*1024, m_hSource)) && !bAbort) { 
    // write to target 
    long bytesWritten = fwrite(buf, 1, bytesRead, m_hTarget); 

    m_lBytesCopied += bytesWritten; 

Дела, клиент сказал, что это довольно медленно по сравнению с нормальными ПК < -> USB скорости. Я не кодировал это, так что это моя работа, чтобы оптимизировать.

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

Я не тот C++ & аппаратный гуру, поэтому я спрашиваю вас, ребята, как я могу ускорить процесс и сохранить успешное копирование.

+2

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

+0

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

+0

Удалите проверку правильности написания байтов. Если вы не можете доверять первой записи, вы не можете доверять следующему чтению, которое вы используете для проверки. (Я предполагаю, что вы проверяете bytesWritten для ошибок.) –

ответ

3
  1. Попробуйте прочитайте/напишите в большом куске. 16M, 32M не плохо для копирования файла.
  2. Если вы всего хотите скопировать файл, который вы всегда можете найти invoke system() Будет быстрее.
  3. Код также проверяет после каждого копирования, если все байты написаны правильно, что также может замедлить процесс.

    Вы можете это проверить, создав hash более крупного куска. Как разбить файл на 64M куски. Затем сопоставьте хэши этих кусков. Протокол Bittorrent имеет эту функцию.

  4. Если у вас есть mmap или MapViewOfFile доступных, карта файл первого. Тогда напишите это на usb. Таким образом, операция чтения будет обрабатываться ядром.

  5. Kerrek только что прокомментировал использование memcpy на mmap. memcpy с 2 mmap ed файл кажется отличным.

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

+1

# 4 звучит хорошо: карта памяти и используйте 'memcpy'. –

+0

@ KerrekSB +1. 'memcpy' с файлом размером 2' mmap кажется отличным вариантом. Обновлен мой вопрос. –

1

Как насчет перекрытия чтений и записей?

В текущем коде общее время составляет time(read original) + time(write copy), если вы читаете первый блок, а во время записи начинаете читать второй блок и т. Д., Ваше общее время будет max(time(read original), time(write copy)) (плюс время чтения/записи первого и последние блоки, которые не будут конвейерными).

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

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

+0

AFAIK, USB I/O также в основном зависит от платформы, не так ли? –

+0

@ AndréCaron Я думаю, да, если вы строите драйвер, но в этом случае я думаю, что он просто обращается к файловой системе, поэтому вы можете «fopen» файлы (и это стандартно). – fortran

0

Я бы просто пошел с некоторыми конкретными функциями ОС, которые наверняка сделают это быстрее, чем что-либо, написанное только с функциями c/C++.

Для Linux это может быть функция sendfile. Для Windows CopyFile это сделает.

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