mmap — предварительная выборка данных из отображаемого в память файла C ++

Я имею дело с очень большими отображенными в память файлами (200+ ГБ), которые не могут быть полностью загружены в память, и доступ к ним осуществляется случайным образом. Сопоставленные файлы хранятся на массиве твердотельных накопителей, но я все еще нахожу, что доступ к необходимым частям по одной очень медленный, если только тот же поиск не был выполнен ранее, а используемые страницы уже были считаны в память.

Добавление нескольких потоков для чтения переменных в mmap одновременно значительно повышает скорость, и мне не удалось достичь верхней границы для улучшения в моем тестировании, но наличие более 1000 потоков приводит к тому, что openmp выдает ошибки, связанные с недоступностью ресурсов.

Я также попробовал madvise, чтобы сообщить ядру о конкретных частях, которые будут необходимы (MADV_WILLNEED), но ядро, кажется, не действует достаточно быстро, чтобы изменить ситуацию.

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

Если нельзя избежать блокирования, также будет работать способ запуска гораздо большего числа очень легких потоков, чтобы сделать чтение.

2

Решение

Вы, кажется, ответили на свой вопрос. Ваше единственное решение, кроме многопоточности, состоит в том, чтобы проходить через любое количество доступов, которые вы можете сделать madvise для каждого. Затем через некоторое количество х madvises (скажем, 10000) вы вернетесь и получите доступ к памяти. Следует отметить, однако, что O / S делает НЕ гарантировать, что ввод / вывод будет выполнен в том порядке, в котором вызывается madvise. Следовательно, O / S может обработать первый madvise, а затем перейти к концу madvise или к тому, который имеет наименьший адрес, в основном, как ему угодно. Просто нет возможности значительно ускорить ввод / вывод до такой степени, как вы хотите.

Пример:

for(i=0; i < accesses + 10000; ++i)
{
madvise(access[i].addr, access[i].length, MADV_WILLNEED);
if(i >= 10000)
{
// Access location access[i-10000].addr
}
}

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]