Подтвердить что ты не робот

Какой правильный размер буфера для функции "написать"?

Я использую функцию ввода-вывода низкого уровня "write" для записи некоторых данных на диск в моем коде (язык C в Linux). Во-первых, я накапливаю данные в буфере памяти, а затем я использую "write" для записи данных на диск, когда буфер заполнен. Итак, какой лучший размер буфера для 'write'? По моим тестам это не тем больше, тем быстрее, поэтому я здесь, чтобы найти ответ.

4b9b3361

Ответ 1

Вероятно, есть некоторые преимущества при записи, которые являются кратными размеру блока файловой системы, особенно если вы обновляете файл на месте. Если вы пишете меньше, чем частичный блок для файла, ОС должна прочитать старый блок, объединить в новое содержимое и затем записать его. Это не обязательно происходит, если вы быстро записываете небольшие фрагменты в последовательности, потому что обновления будут выполняться на буферах в памяти, которые позже будут очищены. Тем не менее, время от времени вы можете вызвать некоторую неэффективность, если вы не заполняете блок (и правильно выровненную единицу: кратное размеру блока при смещении, кратное размеру блока) при каждой операции записи.

Эта проблема с размером передачи не обязательно исчезает с mmap. Если вы сопоставляете файл, а затем memcpy некоторые данные на карте, вы делаете страницу грязной. Эта страница должна быть очищена позже: она неопределенная, когда. Если вы сделаете еще один memcpy, который касается одной и той же страницы, эта страница может быть очищена, и вы снова замариваете ее. Так что это делается дважды. Путь к копированию будет копироваться по краям по краям - размер страницы.

Ответ 2

Вы хотите, чтобы он был кратным размеру страницы ЦП, чтобы максимально эффективно использовать память.

Но в идеале вы хотите использовать mmap вместо этого, чтобы вам никогда не приходилось иметь дело с буферами.

Ответ 3

Вы можете использовать BUFSIZ, определенный в <stdio.h>

В противном случае используйте небольшой кратный размер страницы sysconf(_SC_PAGESIZE) (например, дважды это значение). Большинство Linux-систем имеют 4 Кбайта страниц (что часто совпадает с небольшим кратным размеру блока файловой системы).

Как и другие ответы, использование системного вызова mmap (2) может помочь. У GNU-систем (например, Linux) есть расширение: вторая строка режима fopen может содержать последний m, и когда это произойдет, GNU libc попробуйте mmap.

Если вы имеете дело с данными размером почти с вашей ОЗУ (или половиной), вы можете также использовать madvise (2) для точной настройки производительности mmap.

См. также этот ответ на вопрос, очень похожий на ваш. (Вы можете использовать 64 Кбайт в качестве разумного размера буфера).

Ответ 4

"Наилучший" размер зависит от основной файловой системы.

Запросы stat и fstat заполняют структуру данных struct stat, которая включает следующее поле:

blksize_t st_blksize; /* blocksize for file system I/O */

ОС отвечает за заполнение этого поля блоками write() "хорошего размера". Однако также важно вызвать write() с памятью, которая "хорошо выровнена" (например, результат вызовов malloc). Самый простой способ добиться этого - использовать предоставленный интерфейс потока <stdio.h> (с объектами FILE *).

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

Ответ 5

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