Я хочу ускорить тысячи поисков и все больше чтения вперед в непрерывной части 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*