我使用root权限运行该程序,但它一直在抱怨mmap无法分配内存。代码段如下:
#define PROTECTION (PROT_READ | PROT_WRITE)
#define LENGTH (4*1024)
#ifndef MAP_HUGETLB
#define MAP_HUGETLB 0x40000
#endif
#define ADDR (void *) (0x0UL)
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
int main (int argc, char *argv[]){
...
// allocate a buffer with the same size as the LLC using huge pages
buf = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
if (buf == MAP_FAILED) {
perror("mmap");
exit(1);
}
...}
硬件:我有8G内存。处理器是ivybridge
Uname输出:
Linux mymachine 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
编辑1:perror的输出
mmap: Cannot allocate memory
还添加了一行来打印errno
printf("something is wrong: %d\n", errno);
但输出是:
something is wrong: 12
编辑2:来自/ proc / meminfo的巨大的tlb相关信息
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
答案 0 :(得分:16)
好吧,正如Documentation/vm/hugetlspage.txt建议的那样,
echo 20 > /proc/sys/vm/nr_hugepages
解决了这个问题。在ubuntu 14.04上测试过。同时检查Why I can't map memory with mmap。
答案 1 :(得分:7)
当您使用MAP_HUGETLB
时,mmap(2)调用可能会失败(例如,如果您的系统没有配置大页面,或者某些资源已耗尽),那么您几乎总是应该调用{{1}没有mmap
作为故障恢复。此外,您不应该定义MAP_HUGETLB
。如果未定义(由MAP_HUGETLB
内部的系统头;根据体系结构或内核版本可能不同),请不要使用它!
<sys/mman.h>
内核的Documentation/vm/hugetlspage.txt提到大页面可能是有限的(例如,如果你将// allocate a buffer with the same size as the LLC using huge pages
buf = mmap(NULL, LENGTH, PROTECTION,
#ifdef MAP_HUGETLB
MAP_HUGETLB |
#endif
MAP_PRIVATE | MAP_ANONYMOUS,
0, 0);
#ifdef MAP_HUGETLB
if (buf == MAP_FAILED) {
// try again without huge pages:
buf = mmap(NULL, LENGTH, PROTECTION,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
};
#endif
if (buf == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
传递给内核,或者你通过hugepages=N
或{{1或者,如果没有在内核中配置,等等......)。所以你不确定能得到它们。使用大页面进行仅4K字节的小映射是一个错误(或者可能是失败)。只有在询问许多兆字节(例如1千兆字节或更多)并且始终是优化时(例如,您希望您的应用程序能够在没有它们的情况下在内核上运行),大页面是值得的。
答案 2 :(得分:0)
如果您肯定知道物理内存就足够了,那就是一个实用的解决方案:
echo 1 > /proc/sys/vm/overcommit_memory