Каков правильный размер буфера для функции записи? - PullRequest
16 голосов
/ 12 марта 2012

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

Ответы [ 5 ]

3 голосов
/ 12 марта 2012

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

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

3 голосов
/ 12 марта 2012

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

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

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

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

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

3 голосов
/ 12 марта 2012

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

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

2 голосов
/ 12 марта 2012

«Лучший» размер во многом зависит от базовой файловой системы.

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

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

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

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

1 голос
/ 12 марта 2012

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

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