Какой оптимальный размер буфера?
На самом деле идеальный буфер от много зависит: от размера блоков вашей файловой системы, от кэша и т.д. Если обобщить, то главное не превышать область кэшей процессора, вот про регистры в таких крупных размерах речи и не идет, конечно. Так что можете смело брать ровно столько, сколько на L1 кэш влезет. Пока выше не залезете, то и не попадете в область оперативной памяти, а следовательно не уйдете вниз по кривой перформанса.
Я бы советовал батчить файл на 64кб и не проводить раннюю оптимизацию, написать сначала как есть, а потом уже заниматься такой микро-оптимизацией. Не думаю, что будет большой разлет по перфомансу.
- Вконтакте
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МБ :)