Ускорение нескольких поисков путем предварительного заполнения буферов ifstream - PullRequest
0 голосов
/ 28 февраля 2019

Я хочу ускорить тысячи поисков и все больше чтения вперед в непрерывной части 1G огромного файла (~ 10G) с известным смещением (скажем, 8G).то есть шаблон выглядит так: seek(8.00G), read(128 bytes), seek(8.01G), read(56 bytes) и далее.

Базовый псевдокод - подход 1

int known_offset = 81024;
std::ifstream fs("fname", std::ios_base::in | std::ios_base::binary)
for(int i = 0; i < 1000; i++) {
    fs->seekg(known_offset, std::ios::beg);
    fs->read(buf, 128);
    known_offset += calculate_fwd_offset_based_on_buf(buf)
}

возможное улучшение - подход 2
Я думал об увеличении размера буфера чтения ifstream, чтобы он предварительно выбирал и заполнял буфер, чтобы следующие операции поиска использовали буфер, чтобы избежать / уменьшить поиск диска.Что-то вроде:

char buf[8*1024*1024];
std::ifstream fs("fname", std::ios_base::in | std::ios_base::binary)
fs.rdbuf()->pubsetbuf(buf, 8*1024*1024);
// Remaining code remains same

Теперь я выполнил strace/time команд на подходах из метода (1) и (2).Для подхода (2) требуется больше времени, и в обоих случаях происходит одинаковое количество вызовов LSEEK / read, причем в случае (2) происходит большее чтение, что, как я догадываюсь, объясняет, почему это занимает больше времени.Есть ли способ заставить seekg/read работать так, как ожидалось?

Неудобное решение
Я могу заставить работать описанный выше подход, удалив seekg(next_offset) и выполнив fs.read(buf, num_chars_to_next_offset),Это уменьшает количество операций чтения с 9000 до ~ 40.Я действительно предпочел бы, чтобы это работало для поиска, поскольку я без необходимости копирую символы в буфер noop таким образом. *1024*

...