Оптимальный размер буфера для read-process-write
В моей функции мне нужно прочитать некоторые данные из файла в буфер, манипулировать данными и записать их обратно в другой файл. Файл имеет неизвестный размер и может быть очень большим.
Если я использую небольшой буфер, будет длительный цикл чтения/записи, и это займет много времени. Напротив, длинный буфер означает, что мне нужно потреблять больше памяти. Каков оптимальный размер буфера, который я должен использовать? Является ли этот случай зависимым?
В Windows я видел какое-то приложение типа "Tera copy", которое эффективно управляет огромными файлами. Есть ли какой-либо другой метод или механизм, о которых я должен знать?
Примечание. Эта программа будет работать под Windows.
Ответы
Ответ 1
Посмотрите, что Microsoft должна сказать о размере IO: http://technet.microsoft.com/en-us/library/cc938632.aspx. В основном, они говорят, что вы должны, вероятно, сделать IO в 64K блоках.
На платформах * NIX struct stat
имеет член st_blksize
, который говорит, что должен быть минимальным размером блока ввода-вывода.
Ответ 2
Это действительно зависит от конкретного случая, и вы, вероятно, должны просто написать свою программу, чтобы иметь возможность обрабатывать размер гибкого буфера, а затем попробовать, какой размер оптимален.
Если вы начнете с малого, а затем увеличьте размер буфера, вы, вероятно, достигнете определенного размера, после чего вы не увидите ни малейшего прироста производительности, поскольку процессор тратит большую часть своего времени на выполнение вашего кода и накладные расходы от ввода-вывода становится незначительным.
Ответ 3
Управление памятью всегда зависит от случая и особенно в сочетании с файловыми вводами.
На моей стороне есть два возможных предложения.
1) Используйте фиксированный размер буфера ввода-вывода, например. 64K, 256K, 512KB или 1MB. Но в этом случае, когда объем ввода-вывода больше, чем этот фиксированный размер буфера, вы должны учитывать смещения для завершения ввода-вывода в нескольких итерациях.
2) Используйте размер буфера переменных ввода-вывода, используя malloc(), но это также зависит от определенных факторов. Например, доступная оперативная память в вашей системе и максимальный предел динамического распределения памяти для процесса в вашей ОС.
Ответ 4
Первое правило для этих целей - ориентироваться. Я предполагаю, что вы преждевременно оптимизируете. Если вы делаете реальный файл IO, пропускная способность вашего диска (или любого другого) обычно будет узким местом. Пока вы пишете свои данные в кусках нескольких страниц, производительность не должна сильно меняться.
Что вы можете надеяться сделать, чтобы выполнить вычисления частей данных параллельно с вашей операцией записи. Для этого вам нужно будет сохранить два буфера, который в настоящее время написан, и тот, на котором вы обрабатываете. Затем вы будете использовать асинхронные функции ввода-вывода (aio_write
в системах POSIX, возможно, что-то подобное существует и для Windows) и буферы переключения для каждой итерации.
Ответ 5
Я предлагаю вам использовать размер буфера для размера страницы. Например, размер страницы составляет 4K, тогда вы можете использовать размер буфера 4K для уменьшения контекстных переключателей.
Ответ 6
В то время как я не могу говорить за алгоритм... Использование памяти и использование процессора - классическая дилемма в программировании, и вам, вероятно, следует выбирать в каждом конкретном случае... Так что если система имеет 4 ГБ свободной памяти, вы, очевидно, можете потреблять совсем немного, тогда как если у вас всего 512 МБ, вы должны потреблять очень мало за счет использования процессора. Лучше всего было бы проверить и изменить свой размер программно:)