Linux: большой массив int: mmap vs искать файл?

Предположим, у меня есть набор данных, который представляет собой массив из 32-битных ints (4 ТБ) 1e12, хранящихся в файле на файловой системе 4 ТБ HDD ext4.

Учтите, что данные, скорее всего, являются случайными (или, по крайней мере, кажутся случайными).

// pseudo-code
for (long long i = 0; i < (1LL << 40); i++)
   SetFileIntAt(i) = GetRandInt();

Далее, подумайте, что я хочу читать отдельные int-элементы в непредсказуемом порядке и что алгоритм работает неопределенно (он продолжается).

// pseudo-code
while (true)
   UseInt(GetFileInt(GetRand(1<<40)));

Мы находимся на Linux x86_64, gcc. Вы можете предположить, что система имеет 4 ГБ оперативной памяти (т.е. 1000 раз меньше, чем набор данных)

Ниже приведены два способа доступа к архитектору:

(A) mmap файл в блок памяти 4TB и получить к нему доступ как массив int

(B) откройте (2) файл и используйте поиск (2) и прочитайте (2), чтобы прочитать ints.

Из A и B, которые будут иметь лучшую производительность?, и почему?

Есть ли другой дизайн, который даст лучшую производительность, чем A или B?

Ответы

Ответ 1

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

Предполагая, что кеш неэффективен:

  • Вы можете использовать fadvise, чтобы заранее объявить свой шаблон доступа и отключить чтение.
  • Из-за рандомизации макета адресного пространства в вашем виртуальном адресном пространстве может не быть непрерывного блока 4 ТБ.
  • Если ваш набор данных когда-либо расширяется, проблема с адресным пространством может стать более актуальной.

Итак, я бы пошел с явным чтением.

Ответ 2

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

Я думаю, что 64-битная архитектура + большой вызов файла для файлового подхода с отображением памяти, по крайней мере, для того, чтобы не усложнять аппликацию; Мне сказали, что сложность часто приводит к плохой работе. Однако mmap() обычно используется для последовательного доступа, что не является целью здесь.

Поскольку это чистый случайный доступ, мало шансов, что два доступа будут находиться на одной и той же загруженной RAM-странице. Полная страница 4kb будет заменена с жесткого диска на RAM, только для данных с 4 байтами... Это бесполезная загрузка автобусов и, вероятно, приведет к плохим характеристикам.

Надеюсь на эту помощь.

Ответ 3

Возможно, для линейного набора данных 4 ТБ вам не нужна файловая система. Я предполагаю, что доступ к исходному устройству может принести определенные выгоды.

Также, возможно, есть способ оптимизировать запросы или структуру данных, чтобы кеширование можно было использовать более эффективно?

Ответ 4

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