Производительность fwrite и размер записи - PullRequest
7 голосов
/ 04 декабря 2010

Я записываю большой числовой двумерный массив в двоичный файл (конечный размер ~ 75 МБ).

Я делаю это в системе Linux.Во-первых, есть ли лучший способ или системный вызов, кроме fwrite, чтобы записать файл как можно быстрее?

Во-вторых, если я должен использовать fwrite, то я должен просто записать весь файл как 1 непрерывную строку?*

fwrite( buf, sizeof(float), 6700*6700, fp );

или запишите его как серию фрагментов

fwrite( buf, sizeof(float), 8192, fp );
fwrite( *(buf+8192), sizeof(float), 8192, fp );
....

Если я должен разделить фрагмент на части, насколько большим должен быть каждый фрагмент?

Ответы [ 5 ]

7 голосов
/ 10 мая 2012

Я согласен с Майком и Джеромом по большей части, но ... только для современной ОС. Если вы работаете со встроенной файловой системой флеш-памяти, есть несколько основных исключений. В этой среде, если вы подозреваете fwrite (), инвестируйте в быстрый тест с использованием write () с большими блоками.

Сегодня я обнаружил, что улучшение скорости записи в 4 раза переходит к записи (). Это произошло из-за слоя posix во встроенной ОС, который транскрибировал fwrite () в fputc () s ... лежащий в основе SYNC флэш-файл в этом случае просто удаляется. Функция write () была реализована подпрограммами намного ближе к ОС (Nucleus), в которой запись блоков не была разбита на байты.

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

6 голосов
/ 04 декабря 2010

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

2 голосов
/ 19 декабря 2010

Вы, вероятно, получите более высокую производительность, используя nmap (), создавая пространство для своего массива (виртуальное адресное пространство) и затем записывая в «память», а не на диск.

Пусть система сделает это за вас: она, вероятно, выделит как можно меньше страниц, чего не произойдет с буфером 75 МБ, сброшенным функцией fwrite ().

В мире ограниченных кешей ЦП играть с огромными буферами не стоит (поэтому malloc () использует nmap () для больших выделений). Прикрепив буфер к файлу при настройке nmap (), и перед заполнением буфера вы сохраните в систему МНОГО работы.

1 голос
/ 04 декабря 2010

Вы можете найти источник fwrite в

http://sourceware.org/git/?p=glibc.git;a=blob;f=libio/iofwrite.c;hb=HEAD

Как вы можете видеть, это в свою очередь вызывает IO_sputn, что в итоге заканчивается

http://sourceware.org/git/?p=glibc.git;a=blob;f=libio/fileops.c;hb=HEAD

(в частности, _IO_new_file_xsputn).Как видите, это всегда проходит через буфер stdio.

Так что я бы посоветовал не использовать stdio;запись напрямую с использованием write (2) обойдет эту дополнительную копию.

1 голос
/ 04 декабря 2010

Один кусок быстрее.Для этого есть несколько причин:

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

2) Дисковый ввод / вывод медленный, поэтому ОС обычно пытается реализовать некоторое кэширование на своей стороне.Это означает, что каждый раз, когда вы используете файловый ввод / вывод, будут проводиться дополнительные проверки, если он кэшируется, должен ли он быть кэширован и т. Д.

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