2010-05-06 23 views
27

Windows có VirtualAlloc, cho phép bạn đặt trước một vùng địa chỉ tiếp giáp, nhưng không thực sự sử dụng bất kỳ bộ nhớ vật lý nào. Sau đó khi bạn muốn sử dụng nó (hoặc một phần của nó) bạn gọi VirtualAlloc một lần nữa để cam kết khu vực của các trang được bảo lưu trước đó.Bất kỳ cách nào để đặt trước nhưng không cam kết bộ nhớ trong linux?

Điều này thực sự thực sự hữu ích, nhưng tôi muốn cuối cùng chuyển ứng dụng của tôi sang linux - vì vậy tôi không muốn sử dụng nó nếu tôi không thể chuyển nó sau này. Linux có một cách để làm điều này?

EDIT - Trường hợp sử dụng

Tôi đang nghĩ đến việc bố trí 4 GB hoặc một số ví dụ về không gian địa chỉ ảo, nhưng chỉ có hành nó 64K tại một thời điểm. Điều này sẽ cho tôi một cách không sao chép để phát triển một mảng lên đến 4 GB. Điều này quan trọng, bởi vì kích thước mảng và bản sao của mảng đôi điển hình giới thiệu độ trễ dường như không thể chấp nhận được đối với các mảng rất lớn.

+0

Trường hợp sử dụng nào giữ cho bạn? Tại sao điều quan trọng là phải tách biệt sự khác biệt giữa yêu cầu nếu bạn có thể phân bổ không gian (đặt nó) và thực sự sử dụng không gian trong bộ nhớ? – dlamotte

+0

có vẻ như phân bổ thường xuyên sẽ hoạt động tốt. Trong trường hợp bộ nhớ không được sử dụng, nó sẽ được hoán đổi, và, khi u bắt đầu sử dụng nó, nó sẽ được đưa trở lại mmeory – Drakosha

+1

@xyld: Một khấu trừ khối từ không gian địa chỉ ảo, phần còn lại trích từ bộ nhớ ảo (pagefile). –

Trả lời

25

mmap một tập tin đặc biệt, như /dev/zero (hoặc sử dụng MAP_ANONYMOUS) như PROT_NONE, sau đó sử dụng mprotect cam kết.

+0

Có.C thư viện/hạt nhân có hiệu quả ngầm làm điều này anyway khi bạn phân bổ một đoạn bộ nhớ của bất kỳ kích thước bình thường. Các trang được dành riêng nhưng không thực sự được ánh xạ cho đến khi bạn chạm vào chúng. Ánh xạ/dev/số không (với MAP_PRIVATE) chỉ là một loại đặc biệt của malloc. – MarkR

+1

@MarkR: Điều đó đúng với Linux, đối với một số cài đặt nhất định của sysctl vượt quá vm. Các mmap của '/ dev/zero' phương pháp tiếp cận nên làm việc trên bất kỳ hệ điều hành POSIX bao gồm cả Linux với vm overcommit vô hiệu hóa. Đọc tài liệu quá tải vm, sự kết hợp của '/ dev/zero' và không có quyền ghi là điều khiến cho khối không được tính vào giới hạn cam kết. –

5

Bạn có thể bật chức năng này trên toàn hệ thống bằng cách sử dụng quá tải hạt nhân. Đây thường là cài đặt mặc định trên nhiều bản phân phối.

Dưới đây là lời giải thích http://www.mjmwired.net/kernel/Documentation/vm/overcommit-accounting

+0

Ôi thật tuyệt ... Không thể bật nó chỉ cho một quá trình duy nhất mặc dù huh? – dlamotte

+0

@dlamotte: Thông thường, nó thường được bật theo mặc định trên hệ thống máy tính để bàn. Các hệ thống thời gian thực sẽ cau mày về kiểu hành vi này (và phân trang theo yêu cầu nói chung), nhưng nó có lợi trên các máy tính để bàn và tôi chưa từng gặp một trong những hệ điều hành chưa được bật. Miễn là bạn không bao giờ ghi vào bộ nhớ mà bạn cấp phát (thông qua hầu như bất kỳ phương tiện nào) của hạt nhân chỉ dự trữ nó. –

4

Tương đương với Linux VirtualAlloc()mmap(), cung cấp cùng các hành vi. Tuy nhiên như một người bình luận chỉ ra, việc đặt trước bộ nhớ tiếp giáp là hành vi của các cuộc gọi đến malloc() miễn là bộ nhớ không được khởi tạo (chẳng hạn như calloc() hoặc mã người dùng).

+0

Bạn nói đúng, tôi đã ngạc nhiên khi thấy rằng nó được chỉ định trong tài liệu cho malloc mà bạn đã liên kết. – Eloff

+2

Nhân tiện, với chỉ malloc tôi đã có thể phân bổ chỉ nhút nhát của 128TB không gian địa chỉ ảo trên một máy x64 linux, trong khối 4GB (2^15-3 hoặc hơn) với khoảng 500MB trên không (quá thấp trong thực tế cho có phải là một mục bảng trang cho mỗi trang 4kb ngay cả, nhưng chỉ cần cho một mục 8 byte cho mỗi trang 2MB (các trang lớn trong suốt hỗ trợ trong hạt nhân?) – Eloff

1

"dường như ngẫu nhiên độ trễ không thể chấp nhận cho mảng rất lớn

Bạn cũng có thể xem xét mlock() hoặc mmap() + MAP_LOCKED để giảm thiểu tác động của phân trang. Nhiều CPU hỗ trợ rất lớn (aka lớn) Các trang lớn hơn này có thể giảm thiểu tác động của TLB đối với việc đọc/ghi trực tuyến

+1

Vấn đề vẫn là bản sao, ngay cả khi không phân trang nó quá chậm để sao chép một mảng 2GB để tạo một bộ nhớ 4GB Nếu bạn có thể tránh di chuyển bộ nhớ, bạn sẽ không có độ trễ khi thêm vào phần tử thứ 2 và 1. – Eloff

Các vấn đề liên quan