2010-08-13 2 views
4

Я пишу код C с некоторыми ограничениями в режиме реального времени. Я проверял скорость можно записать на диск с DD:Не удается достичь скорости dd

дд, если =/DEV/нуль =/DEV/SDB шс = 32K кол = 32768 Oflag = прямой

Об этом пишет 1 Гб нулями до/DEV/SDB в 32К блока размером

Я достигать около 103 Мбайт/с с этим

Теперь я программно сделать что-то подобное:

open("/dev/sdb",O_WRONLY|O_CREAT|O_DIRECT|O_TRUNC, 0666); 

я получаю значение временной метки записывать из буфера 32 КБ в/dev/sdb 10 000 раз (в цикле for) получить другое значение времени сделать немного количества хрустов, чтобы получить скорость в МБ/с, и это около 49 МБ/с

Почему я не могу достичь той же скорости, что и dd? В strace показана ту же открытую команду, которую я использую.

+2

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

+0

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

ответ

5

Проверьте, какие системные вызовы dd производит не только открытые, но и последующие read s и writes. Использование правильных размеров буфера может существенно повлиять на эту крупную копию. Обратите внимание, что /dev/zero не является хорошим тестом для бенчмаркинга, если ваша конечная цель - копия диска на диск.

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

+0

Я действительно заинтересован в прямой записи из памяти в/dev/sdb, поэтому я чувствую, что/dev/zero должен работать очень хорошо. И что вы говорите в отношении чтения и записи? Я задаю размер блока в команде как 32K. – dschatz

+1

+1 читать источник dd. Вот почему он есть. – nmichaels

+1

Источник - 2000 строк. Не совсем магнум опус. Просто проверьте это: http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/dd.c. Кажется, он использует чтение, запись, memcpy, memset. Ничего волшебного нет. Кажется, у него есть несколько стратегий для чтения/записи, хотя некоторые из этих вариантов, похоже, предназначены для особых требований к файловой системе/ОС. –

0

Я оставляю часть о соответствии системных вызовов кому-то еще. Этот ответ касается буферизирующей части.

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

При изучении Java я написал простой клон «copy», а затем попытался сопоставить его скорость. Так как код побайтно читал/записывал размер буфера, это действительно изменило ситуацию. Я сам не буферизую, но я просил чтение читать куски определенного размера. Чем больше кусок, тем быстрее он доходил до точки.

Что касается использования размера блока 32K, помните, что ОС по-прежнему использует отдельные буферы ввода-вывода для процессов пользовательского режима. Даже если вы делаете что-то с определенным оборудованием, т. Е. Пишете драйвер для устройства, которое имеет некоторые физические ограничения, например. диск CD-RW с размерами сектора, размер блока является лишь частью истории. У ОС по-прежнему будет свой буфер.

+0

Буфер 32k, который совпадает с размером блока, который я использую в dd. Они переходят в одни и те же системные вызовы, так что еще можно экспериментировать? Также я открываю оба с прямым флагом, поэтому ОС не будет его буферировать. – dschatz

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