У меня есть класс BitVector
, который может либо распределять память динамически, используя new
, либо файл mmap
. Нет заметной разницы в производительности при использовании с небольшими файлами, но при использовании 16-гигабайтного файла я обнаружил, что файл mmap намного медленнее, чем память, выделенная new
. (Что-то вроде 10x медленнее или более.) Обратите внимание, что у моей машины 64 ГБ ОЗУ.mmap в сравнении с памятью, выделенной новым
Этот код загружает значения из большого файла диска и помещает их в фильтр Bloom, который использует мой класс BitVector
для хранения.
Сначала я подумал, что это может быть потому, что резервная копия для файла mmap была на том же диске, что и файл, с которого я загружался, но это, похоже, не было проблемой. Я поставил два файла на два физически разных диска, и никаких изменений в производительности не произошло. (Хотя я считаю, что они находятся на одном контроллере.)
Затем я использовал mlock
, чтобы попытаться заставить все в ОЗУ, но реализация mmap все еще была очень медленной.
Итак, пока я просто выделяю память непосредственно. Единственное, что я изменяю в коде для этого сравнения, это флаг конструктора BitVector
.
Обратите внимание, что для измерения производительности я смотрю на top
и просматриваю, сколько состояний я могу добавить в цветной фильтр в секунду. Использование ЦП даже не регистрируется на top
при использовании mmap
- хотя jbd2/sda1-8
начинает двигаться вверх (я работаю на сервере Ubuntu), который выглядит как процесс, связанный с ведением журнала для диска. Файлы ввода и вывода хранятся на двух жестких дисках.
Может ли кто-нибудь объяснить эту огромную разницу в производительности?
Спасибо!
AFAIK, политика по умолчанию ттара для чтения больших страниц разве довольно хорошо. Можете ли вы повторно запустить свой случай после установки флага MAP_POPULATE и использования madvise также с флагами MADV_SEQUENTIAL (если ваш доступ последователен) или MADV_RANDOM (если произвольный доступ) OR'ed с MADV_WILLNEED (чтобы предотвратить перезагрузку страниц). – Arunmu
Это, безусловно, неожиданное поведение, в частности потому, что 'operator new' использует' malloc', который использует 'mmap' для больших запросов! Когда вы говорите «используя файл 16 ГБ», который предполагает, что вы используете файл _real_, а не один из '/ dev/shm'? Если это так, и, в частности, поскольку вы заметили, что процесс журналирования продолжается, замедление может быть связано с доступом к диску для чтения и при сбое (хотя я не знал, что ОС должна делать на диске для пустых нулевых страниц) , – Damon
@Damon - Я использую настоящий файл, а не временный файл. Я обращаюсь к нему случайным образом, хотя, если его заблокировать в памяти, похоже, это не имеет значения. –