【问题标题】:mmap open and read from filemmap 打开并从文件中读取
【发布时间】:2022-12-09 21:39:49
【问题描述】:

我正在映射一个巨大的文件,以避免我的应用程序抖动到主虚拟内存,并能够使用超过我拥有的 RAM 运行该应用程序。代码是 c++,但部分遵循旧的 c API。当我使用分配的指针时,内存确实会根据需要返回到文件中。但是,当我下次运行该应用程序时,我希望从已经具有准备好的数据的同一个文件中读取内存。出于某种原因,在下一次运行中,我读回了所有零。我究竟做错了什么?是 ftruncate 调用吗?是带有错误标志的 fopen 调用吗?是 mmap 标志吗?

int64_t mmbytes=1<<36;
FILE *file = fopen(filename, "w+");
int fd = fileno(file);
int r = ftruncate(fd, mmbytes );
if (file == NULL || r){
    perror("Failed: ");
    throw std::runtime_error(std::strerror(errno));
} // 

if ((mm = mmap(0, mmbytes,  
        PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0)) == MAP_FAILED)
  {
        fprintf(stderr,"mmap error for output, errno %d\n", errno);
        exit(-1);
  } 
 }

【问题讨论】:

  • 读取文件的代码在哪里?您的矩阵有多大(以字节为单位),它是否等于mmbytessizeof(mymatrix) * DIM?是的,以写入模式打开文件然后从中读取是一个问题。
  • 另请注意,映射一个大文件只会将内存抖动移动到程序中的不同位置(即在读/写时)
  • "w+" 如果文件已经存在则采取行动:销毁内容 - 参见std::fopen
  • 1) 添加了 mmbytes 值。 2) 是的,会有一些颠簸,但访问是按顺序按大块进行的,大约每分钟前进到下一个块。 3)所以? fopen with "r+" 是吗?
  • 按顺序访问大块,每分钟左右前进到下一个块这只是使用mmap() 的最次优方式。 mmap()慢的,特别是对于只读取一次数据的顺序读取。如果文件大于内存,你将要破坏你的虚拟机。只需将open()O_DIRECTread()数据一起使用,并绕过页面缓存,因为数据大于内存,缓存它是没有用的。

标签: c++ mmap


【解决方案1】:
FILE *file = fopen(filename, "w+");

我建议您参考 fopen 的手册页,其中对“w+”的描述如下:

       w+     Open  for  reading  and writing.  The file is created if it does
              not exist, otherwise it is truncated.  The stream is  positioned
              at the beginning of the file.

我特别提请您注意“它被截断”部分。换句话说,如果现有文件中有任何内容,这最终会将其从高轨道上摧毁。

根据您正在做的其他事情,“a”会更好。

更好的办法是完全忘记fopen,而只使用open

int fd=open(filename, O_RDWR|O_CREAT, 0666);

这是您的文件描述符,无需跳过任何环节。文件被创建,如果它已经存在则保持不变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-11
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多