简体   繁体   English

为什么mmap在32位armv7l上的4GB文件成功了?

[英]Why mmap a 4GB file on 32-bit armv7l succeeded?

I had the impression from the mmap(2) man page and search results, that mmap is only limited to system's available address spaces, minus the system reserved address spaces. 我从mmap(2)手册页和搜索结果中得到的印象是, mmap仅限于系统的可用地址空间,减去系统保留的地址空间。 So on 32-bit armv7l, I assume it's around 3GB = (4GB - 1GB). 所以在32位armv7l上,我认为它大约是3GB =(4GB - 1GB)。

But it seemed like I could actually mmap a 5 GB file without any problem: 但似乎我实际上可以毫无问题地mmap 5 GB文件:

int main(int argc, char** argv) {
        // stats
        char * path = argv[1];
        struct stat sb; 
        stat(path, &sb);
        std::cout << "File size: " << sb.st_size << std::endl;  

        // open
        int fd = open(path, O_RDONLY, S_IRWXU);
        std::cout << "File descriptor: " << fd << std::endl;
        int i;
        for (i =0; i<10; ++i){
                void *pa = mmap(
                        nullptr, sb.st_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
                std::cout << "PA: " << pa  
                        << ", MAP_FAILED: " 
                        << (pa == MAP_FAILED) << ", Status: " 
                        << strerror(errno) << std::endl;
        }   
}

Compile with -D_FILE_OFFSET_BITS=64 flag: 使用-D_FILE_OFFSET_BITS=64标志进行编译:

g++  -D_FILE_OFFSET_BITS=64 test.cc

And the result yields: 结果产生:

File size: 5045966585
File descriptor: 3
PA: 0x89f80000, MAP_FAILED: 0, Status: Success
PA: 0x5d34a000, MAP_FAILED: 0, Status: Success
PA: 0x30714000, MAP_FAILED: 0, Status: Success
PA: 0x3ade000, MAP_FAILED: 0, Status: Success
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory

From the results, mmap succeeded for 4 times before going into real troubles. 从结果来看,mmap成功了4次才真正陷入困境。 But it shouldn't have been succeeded since the file is ~5GB. 但它不应该成功,因为文件大约是5GB。

My questions would be: 我的问题是:

  1. Is this behavior expected for mmap ? 这种行为是否适用于mmap
  2. If not, where did I do wrong? 如果没有,我哪里做错了?

Edit: 编辑:

With physical addres extension (PAE) 32-bit systems can addres much more than 2^32 bytes, if that is available. 使用物理地址扩展(PAE),32位系统可以添加超过2 ^ 32个字节(如果可用)。

There's no PAE support for this CPU 此CPU没有PAE支持

$> cat /proc/cpuinfo

Processor       : ARMv7 Processor rev 4 (v7l)
processor       : 0
BogoMIPS        : 1436.46

processor       : 1
BogoMIPS        : 1436.46

Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 4

Hardware        : sun7i
Revision        : 0000
Serial          : 09c11b9d52544848804857831651664b

PAE is irrelevant. PAE无关紧要。 This is not about accessing large amounts of physical memory. 这不是关于访问大量物理内存。

The problem is that your mmap function takes a 32-bit value for the size of the mapping. 问题是您的mmap函数采用32位值作为映射的大小。 So your 64-bit size gets truncated and you're actually allocating less than 1 GB of virtual memory. 因此,您的64位大小会被截断,实际上您实际分配的虚拟内存不到1 GB。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM