Какой оптимальный размер буфера?

Какой оптимальный размер буфера?

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

Я бы советовал батчить файл на 64кб и не проводить раннюю оптимизацию, написать сначала как есть, а потом уже заниматься такой микро-оптимизацией. Не думаю, что будет большой разлет по перфомансу.

  • Facebook
  • Вконтакте
  • Twitter

4ainik, вот, например, ответ на стак-оверфлоу, полностью солидарен с моим ответом.

Дмитрий Threy, оптимальный размер буфера это сферический конь в вакууме, но в большинстве случаев лучше придерживаться диапазона 512 - 64к, кратного степени двойки. Не забывайте, что вы работаете с диском не напрямую, а через API ОС, а там куча посредников и своя логика работы. В любом случае чем больше буфер тем меньше оверхед, ну чисто математически: 1) вызвать 1 раз fwrite(buf, 512, 1); 2) вызвать 512 раз fwrite(buf, 1, 1);

Очевидно второй вариант будет хуже в плане производительности, хотя и вполне уместен для например терминала :)

А конкретно для условий описанных ТС, я бы выбрал максимальный размер буфера равный 64к.

4ainik, мой ответ выше и говорит использовать 64кб, тем самым не выходить за рамки кэша, какой смысл смотреть на результирующий график при таких буферах, если мы говорим использовать одно и тоже?

Я бы предложил ему выйти за размер кэша при батчинге файла на 10гб и вот тогда он почует разницу.

4ainik, какая разница, какой поток? Каждый поток делит время на определенном ядре процессора и часть одного потока в одном регистре и часть другого на том же самом регистре - просто невозможно, такого просто не бывает, вру, на самом деле бывает, если вы не делаете safe-threaded приложений с блоками, но мы же говорим о грамотном написании программ. Так, о чем я, одновременно там будет одно исполнение потока, т.е. если вы написали буфер в 64кб и работаете с ним, то он и попробует вместить туда ровно 64кб.

Или вы мне сейчас хотите сказать, что большинство практик для перформанса, типа inline методов/unroll циклов и выравнивания структур по полям полный бред, потому что мы не знаем, что там внутри? А зря, потому что они как раз нацелены на то, что мы догадываемся, что там внутри и пытаемся сделать лучше.

при копировании файла путем перебора его через внутренний буфер? У вас буфер, это что такое? Правильно, переменная. А где она хранится? Правильно, в кэше процессора, а далее в регистрах.

Будут ли они вообще там храниться? А как вы себе это представляете? Данные, если мы с ними работаем, процессор вообще никак не обойдут, хоть ты лопни, но такого не будет.

4ainik, в регистр лезут переменные из кэша, поделенные на размерность этого регистра, то есть по 64бита и 32бита.

Да не знает процессор о вашей ОЗУ, у него есть память на регистрах. Все взаимодействие с данными происходит именно там, я это уже пытаюсь объяснить час.

А куда она влезет тогда? Где процессор с ней будет общаться? Из оперативной памяти напрямую? Вы в своем уме? Она чанками раскидывается на регистры из кэша.

  • Размер блока 1кб, среднее время = 0:00:0.0226849
  • Размер блока 2кб, среднее время = 0:00:0.021518
  • Размер блока 4кб, среднее время = 0:00:0.0208970
  • Размер блока 8кб, среднее время = 0:00:0.0200017
  • Размер блока 16кб, среднее время = 0:00:0.0200935
  • Размер блока 32кб, среднее время = 0:00:0.0196690
  • Размер блока 64кб, среднее время = 0:00:0.0196175
  • Размер блока 128кб, среднее время = 0:00:0.0202932
  • Размер блока 256кб, среднее время = 0:00:0.0205030
  • Размер блока 512кб, среднее время = 0:00:0.0200344
  • Размер блока 1мб, среднее время = 0:00:0.0250169
  • Размер блока 1кб, среднее время = 00:00:00.6086737
  • Размер блока 2кб, среднее время = 00:00:00.5704494
  • Размер блока 4кб, среднее время = 00:00:00.5701250
  • Размер блока 8кб, среднее время = 00:00:00.5489293
  • Размер блока 16кб, среднее время = 00:00:00.5387132
  • Размер блока 32кб, среднее время = 00:00:00.5380544
  • Размер блока 64кб, среднее время = 00:00:00.5314811
  • Размер блока 128кб, среднее время = 00:00:00.5325442
  • Размер блока 256кб, среднее время = 00:00:00.5379496
  • Размер блока 512кб, среднее время = 00:00:00.5288921
  • Размер блока 1мб, среднее время = 00:00:00.5284209
  • Размер блока 1кб, среднее время = 00:00:04,0827317
  • Размер блока 2кб, среднее время = 00:00:04,0602448
  • Размер блока 4кб, среднее время = 00:00:03,9731101
  • Размер блока 8кб, среднее время = 00:00:03,881938
  • Размер блока 16кб, среднее время = 00:00:03,7614141
  • Размер блока 32кб, среднее время = 00:00:03,8049724
  • Размер блока 64кб, среднее время = 00:00:03,7621202
  • Размер блока 128кб, среднее время = 00:00:03,7688710
  • Размер блока 256кб, среднее время = 00:00:03,7608635
  • Размер блока 512кб, среднее время = 00:00:03,8076113
  • Размер блока 1мб, среднее время = 00:00:03,765408
  • Размер блока 1кб, среднее время = 00:00:48,9506655
  • Размер блока 2кб, среднее время = 00:00:49,0770333
  • Размер блока 4кб, среднее время = 00:00:48,6813174
  • Размер блока 8кб, среднее время = 00:00:47,6786507
  • Размер блока 16кб, среднее время = 00:00:45,6271946
  • Размер блока 32кб, среднее время = 00:00:46,1870477
  • Размер блока 64кб, среднее время = 00:00:45,9454532
  • Размер блока 128кб, среднее время = 00:00:45,157257
  • Размер блока 256кб, среднее время = 00:00:45,0101140
  • Размер блока 512кб, среднее время = 00:00:44,722839
  • Размер блока 1мб, среднее время = 00:00:44,4402667

Никита, ээээ, тут есть несколько моментов. 1) современные жесткие диски обладают большой скоростью чтения/записи в зависимости от модели диска и интерфейса он может выдавать данные со скоростью 100МБайт/сек и более 2) современные ОС умеют очень хорошо кешировать данные в оперативной памяти, вполне себе могут закешировать весь файл целиком. Обычно это легко заметить при чтении файла, в первый раз он читается существенно дольше, последующих.

Не знаю как вы проводили тесты, но тесты на файлах размером меньше 1Гб практически не представляют полезной информации.

ЗЫ: График в данном случае показательнее цифр. ЗЫ2: Какой у вас жесткий диск? уж не SSD? ЗЫ3: Исходный код программы в студию :)

Никита, Понятно :) Т.е. у вас получается измерение среднего времени выполнения операций чтения+записи.

Вот здесь как-то странно выглядит первый столбец (1кБ), по какой-то непонятной причине он показал лучше результат чем следующий (2кБ). 16кБ вполне себе ожидаемо показал результаты гораздо лучше чем все предыдущие, а вот почему 16кБ опередил 32кБ и даже 64кБ - не совсем понятно. Вполне возможно, что здесь работают какие-то особые механизмы кеширования, возможно упреждающего чтения, но могут влиять другие факторы, например фрагментация диска, тип файловой системы, размер кластера и размер сектора (обычно он 512байт, но в некоторых больших дисках бывает 4кБ). Вполне ожидаемо снижение оверхеда программы по мере увеличения размера буфера, вообще интересно посмотреть на картину происходящего по мере дальнейшего увеличения размера буфера до 10МБ :)

📎📎📎📎📎📎📎📎📎📎