簡體   English   中英

在不使用交換的情況下分配最大緩沖區

[英]Allocating largest buffer without using swap

在Linux下的C / C ++中,我需要分配一個大的(幾千兆字節)內存塊,以便存儲連接到以太網端口的傳感器的實時數據和大約110MB / s的流數據。 我想分配盡可能多的內存,以最大化我可以存儲的數據序列的長度。 但是,我還需要確保不會進行磁盤交換,因為產生的延遲和磁盤訪問帶寬有限會導致傳感器(非常有限)的緩沖區溢出。

確定要分配多少內存的最佳方法是什么? 我僅限於分配比報告的可用內存稍小的塊,還是可以更直接地與linux虛擬內存管理器連接?

好吧,在linux下你可以使用mlock()/ mlockall()來保持物理內存中的地址范圍並防止它被換出。 使用mlock的過程需要一些特權來執行此操作,“man mlock”具有詳細信息。 我不確定最大的mlock'able塊(它可能與看似“免費”的塊有所不同),所以可能二進制搜索可能有所幫助(鎖定范圍,如果失敗則減小區域的大小等等。)

另一方面,對於固態硬盤來說,110MB / s並不是真正的問題。 一個60GB的SSD,寫入速度為280MB / s,在拐角處的成本約為200美元。 只需將傳感器數據復制到一個小的寫入緩沖區中,然后將其傳輸到SSD。

如果計算機系統專用於從傳感器接收數據,則可以簡單地禁用交換。 然后分配盡可能大的緩沖區,在系統中留下足夠的內存僅用於基本工具。

如果你malloc的內存所需要的量,並在該速度寫,你還是會被打到由於所有的頁面錯誤(即虛擬內存的每個頁面映射到物理內存,這也可能包括換出內存性能其他過程)。

為了避免這種情況,您可以在開始從傳感器讀取之前將整個分配的緩沖區memset為0,以便將所有需要的虛擬內存映射到物理內存。

如果您只使用可用的物理內存,則根本不應該進行交換。 使用更多將導致其他進程的內存交換到磁盤 - 如果這些進程空閑,它不應該造成任何問題。 如果它們處於活動狀態(即偶爾使用它們的內存),則會發生一些交換 - 可能比硬盤驅動器帶寬低得多。 您使用的內存越多,更多活動進程的內存將被換出,並且會發生更多的HD活動 - 此時,您可以使用的最大內存量具有良好的性能,這幾乎是試驗和錯誤的結果。

通過使用超過可用的物理內存,您肯定會導致內存寫入速率的交換,並且沒有辦法避免這種情況。

確定要分配多少內存的最佳方法是什么?

由於虛擬內存的使用方式,不可交換的內核內存,幾乎不可能確定應用程序可以訪問多少已安裝的內存。

我能想到的最好的是允許用戶配置用於緩沖的內存量。

我僅限於分配比報告的可用內存略小的塊,

報道的免費內存並不是真正的“免費物理內存”。 不幸。

或者我可以更直接地與linux虛擬內存管理器連接?

這可以通過使用自定義設備驅動程序,直接在內核空間中分配內存並通過mmap()提供對它的訪問來完成。 一般不推薦,但適用於您的特殊情況。

但是,我還需要確保不會進行磁盤交換

隨着Linux內核開發的步伐,知識變得非常快,所以我要說的就是我所說的。 您可以嘗試使用以下內容:

  1. SysV共享內存。 它通常不會被交換。 man shmget

  2. tmpfs - 內存中的文件系統。 至少在早期的2.6內核中,內存被固定到RAM,因此無法交換。 要將它用作內存,請在tmpfs上創建一個文件,在文件中write()以強制實際分配內存,然后使用mmap()文件。

分配內存后,你可以

echo 0 > /proc/sys/vm/swappiness

要求內核更喜歡從緩存中回收內存而不是交換內存。

只需0.2美元

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM