Tôi đã có ấn tượng từ trang kết quả tìm kiếm và kết quả tìm kiếm mmap(2)
, rằng mmap
chỉ giới hạn trong không gian địa chỉ có sẵn của hệ thống, trừ đi không gian địa chỉ dành riêng cho hệ thống. Vì vậy, trên armv7l 32-bit, tôi giả sử nó là khoảng 3GB = (4GB - 1GB).Tại sao mmap một tệp 4GB trên armv7l 32 bit đã thành công?
Nhưng dường như tôi có thể thực sự mmap
một file 5 GB không có vấn đề:
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 với -D_FILE_OFFSET_BITS=64
cờ:
g++ -D_FILE_OFFSET_BITS=64 test.cc
Và sản lượng kết quả:
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
Từ kết quả, mmap đã thành công trong 4 lần trước khi đi vào nhóm thực bles. Nhưng nó không nên được thành công kể từ khi tập tin là ~ 5GB.
Câu hỏi của tôi sẽ là:
- là hành vi này dự kiến cho
mmap
? - Nếu không, tôi đã làm gì sai?
Edit:
Với phần mở rộng địa chỉ vật lý (PAE) hệ thống 32-bit có thể địa chỉ nhiều hơn 2^32 byte, nếu đó là có sẵn.
Không có hỗ trợ PAE cho CPU này
$> 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
Không liên quan đến câu hỏi của bạn và chỉ FYI, nhưng khi in một con trỏ sử dụng định dạng 'printf'' "% p" 'đối số * nên * là' void * ', do đó không cần truyền. Ngoài ra còn có một [toán tử đầu ra quá tải] (http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt) lấy một 'void *' được sử dụng để in con trỏ, vì vậy không cần cho bản in C cũ của ' 'chức năng ở tất cả. –
Với hệ thống 32-bit mở rộng vật lý (PAE) có thể thêm nhiều hơn 2^32 byte, nếu có. – hetepeperfan
Nguyên mẫu hàm cho 'mmap()' là gì? Nếu đối số thứ hai chỉ là 32 bit, thì 'sb.st_size' 64 bit của bạn có thể bị cắt bớt. –