Я написал свой диплом бакалавра по поводу сравнения fwrite VS mmap («Эксперимент по измерению эффективности обмена между традиционными вводами и файлами с памятью»). Прежде всего, для записи вам не нужно искать файлы с отображением памяти, особенно для больших файлов. fwrite
полностью прекрасен и почти всегда превосходит подходы, используя mmap
. mmap
даст вам максимальную производительность для параллельного чтения данных; для последовательных данных, записывающих ваше реальное ограничение с fwrite
- это ваше оборудование.
В моих примерах remapSize
является начальным размером файла и размера, с помощью которого файл будет увеличен на каждое переназначении. fileSize
отслеживает размер файла, mappedSpace
представляет размер текущего mmap (его длина), alreadyWrittenBytes
- это байты, которые уже были записаны в файл.
Вот пример инициализационные:
void init() {
fileDescriptor = open(outputPath, O_RDWR | O_CREAT | O_TRUNC, (mode_t) 0600); // Open file
result = ftruncate(fileDescriptor, remapSize); // Init size
fsync(fileDescriptor); // Flush
memoryMappedFile = (char*) mmap64(0, remapSize, PROT_WRITE, MAP_SHARED, fileDescriptor, 0); // Create mmap
fileSize = remapSize; // Store mapped size
mappedSpace = remapSize; // Store mapped size
}
Q1 объявления:
Я использовал "Unmap-Remap" -mechanism.
Unmap
- первые приливы (
msync
)
- , а затем в памяти снимает отображение файла, отображенного.
Это может выглядеть следующим образом:
void unmap() {
msync(memoryMappedFile, mappedSpace, MS_SYNC); // Flush
munmap(memoryMappedFile, mappedSpace)
}
Для Переоформления, у вас есть выбор, чтобы переназначить весь файл или только недавно добавленный часть.
переназначить в основном
- увеличивает размер файла
- создает новую карту пам
Пример реализации для полного переназначить:
void fullRemap() {
ftruncate(fileDescriptor, mappedSpace + remapSize); // Make file bigger
fsync(fileDescriptor); // Flush file
memoryMappedFile = (char*) mmap64(0, mappedSpace + remapSize, PROT_WRITE, MAP_SHARED, fileDescriptor, 0); // Create new mapping on the bigger file
fileSize += reampSize;
mappedSpace += remapSize; // Set mappedSpace to new size
}
Пример реализации для малого переназначить :
void smallRemap() {
ftruncate(fileDescriptor, fileSize + remapSize); // Make file bigger
fsync(fileDescriptor); // Flush file
remapAt = alreadyWrittenBytes % pageSize == 0
? alreadyWrittenBytes
: alreadyWrittenBytes - (alreadyWrittenBytes % pageSize); // Adjust remap location to pagesize
memoryMappedFile = (char*) mmap64(0, fileSize + remapSize - remapAt, PROT_WRITE, MAP_SHARED, fileDescriptor, remapAt); // Create memory-map
fileSize += remapSize;
mappedSpace = fileSize - remapAt;
}
Существует mremap function
там, но он утверждает,
Этого вызов является Linux-конкретным, и не должен использоваться в программах , переносимые.
Q2 объявления:
Я не уверен, если я понял, что правая точка. Если вы хотите сообщить ядру «и теперь загрузите следующую страницу», то нет, это невозможно (по крайней мере, насколько мне известно). Но см. Объявление Q3 о том, как посоветовать ядро.
Q3 объявления:
Вы можете использовать madvise
с флагом MADV_SEQUENTIAL
, но имейте в виду, что это не навязывает ядро читать дальше, но только советы его.
Excerp образуют man:
Это может вызвать ядро агрессивно упреждающего чтения
Личный вывод:
Не используйте mmap
для последовательной записи данных , Это просто вызовет намного больше накладных расходов и приведет к гораздо более «неестественному» коду, чем простому алографическому письму, используя fwrite
.
Использование mmap
для случайного доступа к файлам.
Это также результаты, полученные во время моей диссертации. Я не смог добиться какого-либо ускорения, используя mmap
для последовательного написания, по сути, для этой цели всегда было медленнее.
'mmap' действительно не имеет промежуточный буфер и записывает данные непосредственно по запросу (то же самое для' write' и друзей), космические APIs вещь пользователь обычно избегают. Это также позволяет сократить количество системных вызовов, которые дорого стоить. – edmz
Можете ли вы предоставить контрольные данные для 'mmap' vs' fwrite', а также 'write'? –
Я сравнивал только 'mmap' с' fwrite', с дополнительными параметрами, такими как распараллеливание и боковая нагрузка, однако тезис в настоящее время не полностью завершен и опубликован, поэтому я не уверен, разрешено ли мне публиковать результаты на данный момент , –