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 должен быть хорошим выбором, поскольку он использует деревья . Кроме того, если ваш файл имеет линейное смежное распределение, дерево степени будет состоять из одной записи, что делает поиск тривиально эффективным.