您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

mmap用于写入顺序日志文件以提高速度?

mmap用于写入顺序日志文件以提高速度?

我写了关于fwrite VS mmap( “衡量传统I / O与内存映射文件间的性能折衷的实验”) 的比较学士学位论文。首先,对于写入,您不必去寻找内存映射文件,尤其是大文件fwrite是完全可以的,并且几乎总是会优于使用mmapmmap将为您提供最大的并行数据读取性能提升;用于连续数据写入的真正限制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
}

我使用了“取消映射-重新映射”机制。

取消映射

这看起来可能如下:

void unmap() {
  msync(memoryMappedFile, mappedspace, MS_SYNC); // Flush
  munmap(memoryMappedFile, mappedspace)
}

对于 Remap ,您可以选择重新映射整个文件或仅重新映射新添加的部分。

基本上重新映射

完整重映射的示例实现:

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的,不应在旨在可移植的程序中使用。

我不确定我是否明白这一点。如果您想告诉内核“现在加载下一页”,则不行,这是不可能的(至少据我所知)。但是请参阅 广告第3步 ,了解如何建议内核。

您可以madvise与flag一起使用MADV_SEQUENTIAL,但请记住,这不会强制内核提前读取,而只是建议您这样做。

男子摘录:

这 导致内核主动预读

请勿mmap用于顺序数据写入。与使用编写简单的算法相比,它只会导致更多的开销,并且会导致更多的“非自然”代码fwrite

使用mmap随机访问读取大型文件

这也是我论文期间获得的结果。通过使用mmap顺序写入,我无法实现任何提速,实际上,这样做总是较慢。

其他 2022/1/1 18:23:05 有420人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶