mmap () против блоков чтения - PullRequest
       53

mmap () против блоков чтения

159 голосов
/ 05 сентября 2008

Я работаю над программой, которая будет обрабатывать файлы, которые могут иметь размер 100 ГБ или более. Файлы содержат наборы записей переменной длины. Я запустил и запустил первую реализацию и теперь стремлюсь повысить производительность, особенно в том, что касается более эффективного выполнения операций ввода-вывода, поскольку входной файл сканируется много раз.

Есть ли практическое правило использования mmap() в сравнении с чтением в блоках с помощью библиотеки C ++ fstream? То, что я хотел бы сделать, это прочитать большие блоки с диска в буфер, обработать полные записи из буфера, а затем прочитать больше.

Код mmap() потенциально может стать очень запутанным, поскольку блоки mmap должны лежать на границах размера страницы (мое понимание), и записи могут потенциально располагаться за границами страницы. С помощью fstream s я могу просто перейти к началу записи и начать чтение снова, поскольку мы не ограничены блоками чтения, которые лежат на границах размера страницы.

Как я могу выбрать между этими двумя вариантами, не записывая сначала полную реализацию? Какие-нибудь практические правила (например, mmap() в 2 раза быстрее) или простые тесты?

Ответы [ 12 ]

1 голос
/ 13 декабря 2009

Я думаю, что самая большая вещь в mmap - это возможность асинхронного чтения с:

    addr1 = NULL;
    while( size_left > 0 ) {
        r = min(MMAP_SIZE, size_left);
        addr2 = mmap(NULL, r,
            PROT_READ, MAP_FLAGS,
            0, pos);
        if (addr1 != NULL)
        {
            /* process mmap from prev cycle */
            feed_data(ctx, addr1, MMAP_SIZE);
            munmap(addr1, MMAP_SIZE);
        }
        addr1 = addr2;
        size_left -= r;
        pos += r;
    }
    feed_data(ctx, addr1, r);
    munmap(addr1, r);

Проблема в том, что я не могу найти нужные MAP_FLAGS, чтобы дать подсказку, что эта память должна быть синхронизирована из файла как можно скорее. Я надеюсь, что MAP_POPULATE дает правильную подсказку для mmap (то есть он не будет пытаться загрузить все содержимое до возврата из вызова, но сделает это в асинхронном режиме с feed_data). По крайней мере, это дает лучшие результаты с этим флагом, даже если руководство заявляет, что ничего не делает без MAP_PRIVATE начиная с 2.6.23.

1 голос
/ 06 сентября 2008

Это звучит как хороший вариант использования для многопоточности ... Я думаю, вы могли бы довольно легко настроить один поток для чтения данных, в то время как другой обрабатывает их. Это может быть способом значительно увеличить воспринимаемую производительность. Просто мысль.

...