LINUX.ORG.RU

Буфферизированное чтение бинарного файла на C++

 ,


0

2

Всегда как то с неохотой пользовался и не желал разбираться в плюсовых *stream, а тут понадобилось. В общем, задача - максимально быстро читать бинарные данные (например, int) из файла, заняв при этом не более точно известного количества памяти для этого чтения (данных много, счет идет на десятки-сотни мегабайт). Куда они потом идут - не суть.

мой вариант (черновой пример, показывающий идею).

std::ifstream file("data", std::ios::binary);
char* buffer = new char[MAX_MEMORY];
file.rdbuf()->pubsetbuf(buffer, MAX_MEMORY);
//blablabla
//читаем int
int value;
file.read(reinterpret_cast<char*>(&value, sizeof(value));
Вопросы: я правильно понимаю, что данные из файла будут читаться в мой буффер, кусками размером MAX_MEMORY, и когда я делаю read, я читаю из этого буфера? Вообще правильно я все делаю? Есть ли способ лучше (если говорить о другом способе, то требования: кроссплатформенность, не использовать никаких либ кроме stl и boost).



Последнее исправление: CatsCantFly (всего исправлений: 1)

Ответ на: комментарий от TrueTsar1C77

Не путай теплое с мягким. pagefault это событие генерируемое MMU когда происходит обращение к страницы отсутствующей в VM процесса. При обычном read в общем случае читается в уже существующий буфер, для которого уже выделена и подшита в VM физическая страница памяти, следовательно никакого pagefault, даже если чтение присходит из «холодного» файла, который еще не закеширован в page cache.

В mmap же при чтении холодного файла как раз и случится pagefault, потому что произойдет обращение к странице, которой еще нет либо физически (major page fault). Может случитс я и minor pagefault, когда страница есть в page cache, но процесс ее с тех пор как она оказалась в page cache ни разу ее еще не читал, тогда тоже случится pagefault (== MMU увидит и сообщит, что происходит обращение к страницы, которой нет ни в VM процесса), но чтения с диска при этом не случится, страница будет найдена в page cache и подшита в VM процесса.

redbaron ★★
()
Ответ на: комментарий от redbaron

Не путай теплое с мягким. pagefault это событие генерируемое MMU когда происходит обращение к страницы отсутствующей в VM процесса.

Никого не интересует pagefault как событие, которое выпиливается префолтом - интересует всех обработкик. Который и при риде и при пейджфолте с дефолтным ммапом будет один и тот же.

При обычном read в общем случае читается в уже существующий буфер, для которого уже выделена и подшита в VM физическая страница памяти

Уважаемый эксперт, а где вы возмёте этот «существующий буфер»?

Буферок в килобайт для поточного днища, дак оно никому не интересно. Ну и это частный случай.

По остальной пасте - не надо мне рассказывать тут куллстори.

TrueTsar1C77
()
Ответ на: комментарий от TrueTsar1C77

Ну т.е. что при read в общем случае нет pagefault мы думаю договорились? Идем дальше.

Обработчику больше работы в случае pagefault и меньше в случае read. И там и там может (а может и не) быть чтение с диска, но в случае pagefault надо еще работать со страницами в VM процесса, а это не бесплатно. Доказать очень просто. Берем файл размером в гиг, читаем его пару раз чтобы весь в page cache надежно влез и запускаем по очереди две программы:

1) одна делает mmap его 1024 раза и читает рандомные куски из рандомной мапы (можешь сделать 1024 симлинка для верности). Итого 1TB страниц в VM процесса.

2) другая открывает его 1024 раза и делает pread тех же рандомных кусков в один единственный буфер.

Замерь время и получишь значение насколько mmap дороже read.

По поводу буферка вот только ничего говорить не надо, мы говорим об общем случае, все программы разные и всем буферки нужны разные. (grep справляется с буферком например). Речь идет о mmap vs read давай их и обсуждать

redbaron ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.