Почему mmap () быстрее последовательного ввода-вывода?

Возможное дублирование:
mmap () против блоков чтения

Я слышал (читал где-то в Интернете), что mmap() быстрее, чем последовательный ввод-вывод. Это правильно? Если да, то почему быстрее?

  • mmap() не читает последовательно.
  • mmap() должен получать данные с самого диска так же, как read()
  • Отображаемая область не является последовательной - поэтому нет DMA (?).

Значит, mmap() действительно должен быть медленнее, чем read() из файла? Какие из моих предположений выше неверны?


person Lunar Mushrooms    schedule 22.03.2012    source источник
comment
@Mehrdad Я видел в интернете комментарии о том, что mmap быстрее   -  person Lunar Mushrooms    schedule 22.03.2012
comment
stackoverflow.com/ questions / 258091 /   -  person Kumar Alok    schedule 22.03.2012
comment
mmap, вероятно, быстрее, чем fread, хотя бы потому, что требуется меньше буферизации. Но я не уверен, что это так быстро, как вы думаете. (В любом случае, когда вам действительно нужно выполнить ввод-вывод диска, диск является узким местом).   -  person Basile Starynkevitch    schedule 22.03.2012
comment
Вы должны поставить эксперимент и рассчитать время для себя, чтобы убедиться, что эти комментарии в Интернете правдивы. Я прочитал в Интернете много неправдивых комментариев.   -  person Crashworks    schedule 22.03.2012
comment
Бен Коллинз уже опубликовал подробный ответ по этому поводу. Для меня это дубликат.   -  person Coren    schedule 22.03.2012
comment
@Coren - я не согласен. Он просто эмперически показывает, что это быстрее, что является отправной точкой для этого вопроса. Здесь возникает вопрос: почему, и ответ Бена вообще не затрагивает этот вопрос.   -  person T.E.D.    schedule 31.12.2013


Ответы (3)


Я слышал (читал где-то в Интернете), что mmap () быстрее, чем последовательный ввод-вывод. Это правильно? Если да, то почему быстрее?

Может быть - есть плюсы и минусы, перечисленные ниже. Если у вас действительно есть причины для беспокойства, всегда сравнивайте оба показателя.

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

1) mmap () не читает последовательно. 2) mmap () должен извлекать данные с самого диска так же, как read (). 3) Отображаемая область не является последовательной - поэтому нет DMA (?).

Итак, mmap () действительно должен быть медленнее, чем read () из файла? Какие из моих предположений выше неверны?

1) неверно ... mmap() назначает область виртуального адресного пространства, соответствующую содержимому файла ... всякий раз, когда осуществляется доступ к странице в этом адресном пространстве, обнаруживается, что физическая оперативная память поддерживает виртуальные адреса, и соответствующее содержимое диска попадает в эту ОЗУ. Таким образом, порядок чтения с диска соответствует порядку доступа. Это «ленивый» механизм ввода-вывода. Если, например, вам нужно было проиндексировать огромную хеш-таблицу, которая должна была быть считана с диска, то mmap создание файла и начало доступа означает, что дисковый ввод-вывод не выполняется последовательно и, следовательно, может привести к увеличению времени, прошедшего до тех пор, пока весь файл считывается в память, но пока это происходит, поиск выполняется успешно и может выполняться зависимая работа, и если части файла на самом деле никогда не нужны, они не читаются (учитывайте детализацию страниц диска и памяти, а также даже при использовании отображения памяти многие ОС позволяют указать некоторые советы по повышению производительности / эффективности памяти о запланированных шаблонах доступа, чтобы они могли упреждающе читать вперед или более агрессивно высвобождать память, зная, что вы вряд ли вернетесь к ней).

2) absolute true (абсолютно верно)

3) «Отображаемая область не является последовательной» нечетко. Отображенные области памяти являются «смежными» (последовательными) в виртуальном адресном пространстве. Выше мы обсуждали последовательный дисковый ввод-вывод. Или вы думаете о другом? В любом случае, пока страницы ошибаются, они действительно могут быть переданы с использованием DMA.

Кроме того, есть и другие причины, по которым отображение памяти может превосходить обычный ввод-вывод:

  • there's less copying:
    • often OS & library level routines pass data through one or more buffers before it reaches an application-specified buffer, the application then dynamically allocates storage, then copies from the I/O buffer to that storage so the data's usable after the file reading completes
    • memory mapping allows (but doesn't force) in-place usage (you can just record a pointer and possibly length)
      • continuing to access data in-place risks increased swapping later: the file/memory-map could be more verbose than data structures into which it could be parsed, so access patterns on data therein could have more delays to fault in more memory pages
  • отображение памяти может упростить задачу синтаксического анализа приложения, позволяя приложению обрабатывать все содержимое файла как доступное, а не беспокоиться о том, когда читать другой буфер заполнен
  • приложение больше полагается на мудрость ОС относительно количества страниц, которые находятся в физической ОЗУ в любой момент времени, эффективно разделяя дисковый кеш прямого доступа с приложением
  • как комментарии доброжелателей ниже, «используя отображение памяти, вы обычно используете меньше системных вызовов»
  • если несколько процессов обращаются к одному и тому же файлу, они должны иметь возможность совместно использовать физические резервные страницы

Это также причины, по которым mmap может работать медленнее - прочтите сообщение Линуса Торвальда здесь который говорит о mmap:

... игры со страничными таблицами вместе с ошибками (и даже просто промахами TLB) легко превышают затраты на копирование страницы в хорошей потоковой манере ...

И из другого его сообщений:

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

  • ошибка страницы стоит дорого. Вот как заполняется маппинг, и это довольно медленно.

FWIW, в последний раз, когда это возникало у меня на работе, ввод с отображением памяти был на 80% быстрее, чем fread и другие, для чтения записей двоичной базы данных в проприетарную базу данных на 64-битном Linux с файлами ~ 170 ГБ.

person Tony Delroy    schedule 22.03.2012
comment
Хороший ответ. Также, используя отображение памяти, вы обычно используете меньше системных вызовов. Это может привести к значительному ускорению чтения с произвольным доступом (т.е. lseek перед каждым read). - person well-wisher; 22.03.2012
comment
@ доброжелатель: хорошее замечание, я добавлю это к списку выше ... ура - person Tony Delroy; 23.03.2012
comment
Хотя это дублированный вопрос, этот ответ кажется более ясным, чем другие ответы в этом сообщении ... - person sleepsort; 20.08.2014
comment
Отличный ответ, но было бы намного лучше, если бы он сравнивал производительность mmap() с, скажем, pread() на дескрипторе файла, открытом с помощью O_DIRECT. fread() находится в буфере и будет использовать неизвестное количество системных вызовов для фактического чтения данных. На 80% быстрее, чем у fread больше, чем немного, кого это волнует? об этом. Без дополнительных данных под капотом любой операции на основе stdio происходит слишком много неизвестного, чтобы это могло быть окончательным эталонным значением. - person Andrew Henle; 17.06.2017

  1. mmap() может делиться между процессами.
  2. По возможности будет использоваться DMA. DMA не требует непрерывной памяти - многие высокопроизводительные карты поддерживают DMA с разбросом и сбором данных.
  3. Если возможно, область памяти может использоваться совместно с кешем блоков ядра. Так что есть копирование у арендодателя.
  4. Память для mmap выделяется ядром, она всегда выровнена.
person J-16 SDiZ    schedule 22.03.2012

«Быстрее» в абсолютном выражении не существует. Вам нужно будет указать ограничения и обстоятельства.

mmap () не читает последовательно.

что заставляет вас думать, что? Если вы действительно последовательно обращаетесь к отображаемой памяти, система обычно выбирает страницы в этом порядке.

mmap () должен получать данные с самого диска так же, как и read ().

конечно, но ОС определяет время и размер буфера

Отображаемая область не является последовательной - поэтому нет DMA (?).

см. выше

Помогает mmap то, что не задействован дополнительный буфер пользовательского пространства, «чтение» происходит там, где ядро ​​ОС считает нужным, и фрагментами, которые можно оптимизировать. Это может быть преимуществом в скорости, но, прежде всего, это просто интерфейс, который проще в использовании.

Если вы хотите узнать о скорости для конкретной установки (оборудование, ОС, шаблон использования), вам нужно будет измерить.

person Jens Gustedt    schedule 22.03.2012