Я использую mmap/read + BZ2_bzDecompress для последовательной распаковки большого файла (29 ГБ). Это сделано потому, что мне нужно проанализировать несжатые данные xml, но мне нужны только небольшие их фрагменты, и казалось, что было бы намного эффективнее делать это последовательно, чем распаковывать весь файл (400 ГБ без сжатия), а затем анализировать его. Интересно, что часть распаковки уже очень медленная — в то время как команда оболочки bzip2 может выполнять чуть больше 52 МБ в секунду (используется несколько запусков timeout 10 bzip2 -c -k -d input.bz2 > output
и делится полученный размер файла на 10), моя программа не может сделать даже 2 МБ/с. , замедляясь через несколько секунд до 1,2 МБ/с
Файл, который я пытаюсь обработать, использует несколько потоков bz2, поэтому я проверяю BZ2_bzDecompress
на BZ_STREAM_END
и, если это происходит, использую BZ2_bzDecompressEnd( strm );
и BZ2_bzDecompressInit( strm, 0, 0 )
для перезапуска со следующим потоком, если файл не был полностью обработан. Я также пробовал без BZ2_bzDecompressEnd
, но это ничего не изменило (и я не вижу в документации, как правильно обрабатывать несколько потоков)
Файл был mmap'ирован ранее, где я также пробовал разные комбинации флагов, в настоящее время MAP_RDONLY
, MAP_PRIVATE
с madvise до MADV_SEQUENTIAL | MADV_WILLNEED | MADV_HUGEPAGE
(я проверяю возвращаемое значение, и madvise не сообщает о каких-либо проблемах, и я на ядре linux Установка Debian 3.2x с поддержкой огромных страниц)
При профилировании я удостоверился, что, кроме некоторых счетчиков для измерения скорости и printf, который был ограничен раз в n итераций, больше ничего не запускалось. Также это на современном многоядерном серверном процессоре, где все остальные ядра простаивают, и это голое железо, а не виртуализированное.
Любые идеи о том, что я мог делать неправильно/делать для повышения производительности?
Обновление: благодаря предложению Джеймса Чонга я попытался «поменять местами» mmap()
на read()
, и скорость осталась прежней. Так что похоже проблема не в mmap()
(либо в этом, либо в mmap()
и read()
есть общая проблема)
Обновление 2: Подумав, что причиной могут быть вызовы malloc/free, выполненные в bzDecompressInit/bzDecompressEnd, я установил bzalloc/bzfree структуры bz_stream в пользовательскую реализацию, которая выделяет память только в первый раз и не освобождает ее, если не установлен флаг. set (передается параметром opaque = strm.opaque). Работает отлично, но опять же скорость не увеличилась.
Обновление 3: я также попробовал fread() вместо read(), и скорость осталась прежней. Также пробовал разное количество прочитанных байтов и размеры буфера распакованных данных - без изменений.
Обновление 4: скорость чтения определенно не является проблемой, так как я смог достичь скорости, близкой к 120 МБ/с при последовательном чтении, используя только mmap().
read()
), чтобы увидеть, есть ли проблема сmmap
. Также может быть, что вы связываетесь с отладочной версией библиотеки bz2? - person James Chong   schedule 11.09.2013bzip.org
, в противном случае я воздержусь от дальнейшие комментарии, пока у меня не будет возможности проверить это. - person James Chong   schedule 12.09.2013