以下是我在 ubuntu 中使用大页面映射文件的代码,但此调用失败并出现错误“无效参数”。然而,当我通过 mmap 中没有文件描述符参数的 MAP_ANON 标志,然后它就可以工作了。我无法理解这背后的可能原因。
其次,我无法理解为什么允许使用 MAP_PRIVATE 进行文件映射,而此标志本身意味着不会将任何更改写回文件。这始终可以使用 MAP_ANON 来完成,还是我遗漏了什么?
有人可以帮我解决这些问题吗?
int32_t main(int32_t argc, char** argv) {
int32_t map_length = 16*1024*1024; // 16 MB , huge page size is 2 MB
int32_t protection = PROT_READ | PROT_WRITE;
int32_t flags = MAP_SHARED | MAP_HUGETLB;
int32_t file__ = open("test",O_RDWR|O_CREAT | O_LARGEFILE,s_IRWXU | S_IRGRP | S_IROTH);
if(file__ < 0 ) {
std::cerr << "Unable to open file\n";
return -1;
}
if (ftruncate(file__, map_length) < 0) {
std::cerr
<< "main :: unable to truncate the file\n"
<< "main :: " << strerror(errno) << "\n"
<< "main :: error number is " << errno << "\n";
return -1;
}
void *addr= mmap(NULL, map_length, protection, flags, file__, 0);
if (addr == MAP_FAILED) {
perror("mmap");
return -1;
}
const char* msg = "Hello World\n";
int32_t len = strlen(msg);
memcpy(addr,msg,len);
munmap(addr, map_length);
close(file__);
return 0;
}
最佳答案
您的两个问题都归结为同一点:使用 mmap() 您可以获得两种映射:匿名内存和文件。
匿名内存(如手册页中所述)不受文件系统中任何文件的支持。相反,您从 MAP_ANON 调用 mmap() 获得的内存是普通系统内存。这个接口(interface)的主要用户是 C 库,它使用它来获取 malloc/free 的后备存储。因此,使用 MAP_ANON 明确表示您不想映射文件。
File-backed memory 将文件(或文件的一部分)混合到应用程序的地址空间中。在这种情况下,内存内容实际上是由文件内容支持的。将 MAP_PRIVATE 标志视为首先为文件分配内存,然后将内容复制到该内存中。事实上,这不会是内核正在做的事情,但让我们假装吧。
HUGE_TLB 是内核为匿名内存提供的一项功能(请参阅 mmap() 手册页中引用的 Documentation/vm/hugetlb-page.txt)。这应该是在对文件使用 HUGETLB 时 mmap() 调用失败的原因。 *编辑:不完全正确。有一个支持大页面的 RAM 文件系统 (hugetlbfs)。但是,根据我对文档的理解,huge_tlb 映射不适用于任意文件。*
有关如何使用 HUGE_TLB 和相应的内存文件系统 (hugetlbfs) 的详细信息,您可能需要考虑 LWN 上的以下文章:
- Huge Pages, Part 1 (简介)
- Huge Pages, Part 2 (接口(interface))
- Huge Pages, Part 3 (行政)
- Huge Pages, Part 4 (基准测试)
- Huge Pages, Part 5 (TLB 成本)
关于c++ - Ubuntu 10.04,将 MAP_HUGETLB 与 MAP_SHARED 一起使用时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6575010/