Malloc против Mmap в C - PullRequest
       15

Malloc против Mmap в C

37 голосов
/ 16 ноября 2009

Я построил две программы, одну из которых malloc, а другую - mmap. Время выполнения с использованием mmap намного меньше, чем с использованием malloc.

Я знаю, например, что когда вы используете mmap, вы избегаете вызовов чтения / записи в систему. И доступ к памяти меньше.

Но есть ли другие причины для преимуществ при использовании mmap над malloc?

Большое спасибо

Ответы [ 6 ]

13 голосов
/ 16 ноября 2009

Я предполагаю, что вы имеете в виду использование mmap и malloc для чтения данных из файлов. В этом случае вы в значительной степени поняли главное:

  • используя fread / fwrite, вы должны совершать много звонков в ОС.
  • используя mmap, вы получаете доступ ко всему файлу за одну операцию. Это не совсем так, потому что ОС, вероятно, отображает файл по одной странице памяти за раз, но все равно намного быстрее.
10 голосов
/ 16 ноября 2009

mmap фактически не загружает файл в память, поэтому он будет загружаться быстрее, но редактирование будет медленнее.

Другой момент заключается в том, что mmap не использует память, но занимает адресное пространство. На 64-битной машине большая часть адресного пространства памяти не будет иметь памяти, поэтому вы можете загружать огромные файлы, скажем, 5 ГБ, которые вы не захотите использовать в malloc.

8 голосов
/ 02 марта 2013

Malloc и mmap иногда работают медленно. В основном это зависит от модели использования:

ММАП: Подсистема подкачки ядра работает в единицах размера страницы. Это означает, что если вы хотите прочитать целую страницу из файла и хотите сделать это многократно (хорошая локализация), это будет хорошо с mmap. Наоборот, если вы отобразите этот файл размером 5 Гб и будете иметь разрозненный доступ, у вас будет много мест для обмена ядром. В дополнение к фактическому вводу / выводу управление страницей займет некоторое время. Если у вас есть опасения по поводу задержки, избегайте этой схемы доступа, так как механизм восстановления страниц Linux имеет тенденцию быть взрывным и приведет к заметным задержкам, а отравление кэша замедлит другие процессы.

таНос: Это хорошо, когда вам нужна память, которая не в единицах размера страницы. но вы не можете делать такие вещи, как mlock () разумно. С точки зрения ввода / вывода скорость очень сильно зависит от того, как вы это делаете. fread / fwrite может отображать страницы за кулисами или выполнять буферизацию в пользовательском пространстве. Локализованный доступ будет довольно быстрым. чтение / запись проходят непосредственно через ядро, поэтому небольшие распределенные доступы по-прежнему будут вызывать операции ввода-вывода из-за пропусков кэша, но фактические данные, передаваемые из пространства ядра-> пользователя, будут немного меньше. Я не знаю, измеримо ли это.

Если только mlock () не редактируется, пользовательские страницы могут быть выгружены / записаны в любое время. Это тоже требует времени. Таким образом, в системах с небольшим объемом памяти победит вариант, отображающий наименьшее количество памяти. В ядре Linux каждая система имеет слишком мало памяти, поскольку неиспользуемые страницы используются для кэширования ввода-вывода, и ядро ​​может занять заметное время, чтобы сделать их доступными, если используется память или интенсивен ввод-вывод.

8 голосов
/ 22 октября 2010

Слушайте, ребята, вопреки распространенному мнению, mmap действительно является функцией выделения памяти, похожей на malloc.

файл mmaped используется только один раз. Вы можете использовать его как функцию выделения памяти, передавая -1 в качестве дескриптора файла.

так что .. обычно используется malloc для крошечных объектов и mmap для больших ..

это хорошая стратегия ..

Я использую alloca () для переменных области действия функции.

1 голос
/ 16 ноября 2009

mmap на самом деле не читает файл. Это просто отображает его в адресное пространство. Вот почему это так быстро, дискового ввода-вывода не будет, пока вы фактически не получите доступ к этой области адресного пространства.

malloc - это просто отображение адресного пространства в памяти

0 голосов
/ 25 марта 2016

По mmap ОЗУ не предоставляется.Предоставляется адресное пространство.

При обращении к адресному пространству возникает ошибка страницы.При сбое страницы в размере страницы, обычно 4096 байт, предоставляется ОЗУ.

Содержимое ОЗУ также предоставляется.Если файлом задано адресное пространство, появится содержимое файла.Если MAP_ANONYMOUS поддерживает адресное пространство, то появляется ОЗУ, инициализированное нулем.

Описанные выше две блага описаны.Во-первых, точно так же, как желаемый ОЗУ может быть инициализирован.Во-вторых, до тех пор, пока не будет предоставлена ​​необходимая оперативная память.

Для запроса адреса менее 2 мегабайт, выполняемого malloc, разрыв программы расширяется.Пока предоставляются адреса, близкие к разрыву программы, разрыв программы не может быть заключен.Поэтому освободившееся ядро ​​ОЗУ может быть не возвращено.Аналогия следует.Можно ли удалить носки перед ботинками?

При вызове munmap к ОЗУ ядра возвращается сразу.Благодаря использованию mmap и munmap вероятность свопа уменьшается.С помощью malloc возможна перестановка расширения программы.

С помощью malloc может быть выделено меньше памяти, чем размер страницы.Разрывная память становится.Память ядра также может фрагментироваться.Ни один из них не идеален.

На любом неработающем процессоре ядро ​​ОЗУ может быть дефрагментировано.Создаются прозрачные огромные страницы размером 2 мегабайта.По сравнению с 512 ошибками страницы, чтобы обеспечить 2M. Когда одной ошибкой страницы может быть обеспечено 2M, достигается значительное повышение производительности.

По mmap существует по крайней мере одна заметная проблема.Для поддержки mmap может использоваться дескриптор файла канала.Ошибка не становится.Однако в адресе памяти данные из предоставленного канала не отображаются.

Однако, если используется MAP_ANONYMOUS, то из дескриптора файла канала в предоставленный адрес mmap данные могут быть прочитаны.Хотя не так эффективно, желаемый результат становится.По неудачному возврату lseek и ошибочно может быть идентифицирован дескриптор файла, прикрепленного к каналу.

На компьютерах, которые могут адресовать весь мегабайт и использовать операционную систему на основе диска, использование malloc необходимо.Если вы используете функцию getline из библиотеки C, то, вероятно, будут использоваться malloc и free.

В операционной системе с управлением ядром вместо mmap зачем использовать malloc?По сравнению с malloc;ММАП кажется сложным?Для вызова munmap необходимо также указать ранее запрошенное количество адресного пространства.использование malloc более переносимо?malloc кажется более удобным?

Тем не менее, если требуется производительность, тогда используется mmap.

Последнее, но не в последнюю очередь, если MAP_SHARED, то с процессами потомства можно обмениваться данными.Избегание pthreads имеет первостепенное значение.Иногда клонирования также можно избежать.

Хотя субъективные методы распределения переменных, перечисленные в наиболее и менее предпочтительных вариантах, следующие: register / stack;ММАП;Глобальный;таНос.К каждому относятся разные блага и изгнания.По достаточно сложной программе;используются три или, возможно, все четыре метода.

...