簡體   English   中英

在64位(或32位)Windows上以32位進程訪問> 2,3,4GB文件

[英]Accessing >2,3,4GB Files in 32bit Process on 64bit (or 32bit) Windows

免責聲明:對於這個問題的冗長性,我深表歉意(不過,我認為這是一個有趣的問題!),但我不知道如何更簡潔地表達它。

我已經進行了數小時的研究,涉及從/LARGEADDRESSAWAREVirtualAllocEx AWE范圍內解決在64位Windows 7上以32位進程訪問多GB文件的方法。 我在Windows中編寫多視圖內存映射的系統(CreateFileMapping,MapViewOfFile等)有些自在,但不能完全避免有解決此問題的更優雅解決方案的感覺。 另外,盡管它們看起來很輕巧,但我非常了解Boost的進程間模板和iostream模板,需要花費大量的精力來編寫僅使用Windows API調用的系統(更不用說我已經擁有一個內存,使用Windows API調用半實現的映射架構)。

我正在嘗試處理大型數據集。 該程序依賴於預編譯的32位庫,因此,即使系統是64位且具有64位OS,目前程序本身仍在32位進程中運行。 我知道有一些方法可以圍繞此添加包裝器庫,但是,由於它是較大代碼庫的一部分,因此確實有些艱巨。 我將二進制標頭設置為允許/LARGEADDRESSAWARE (以減少我的內核空間為代價?),這樣我就可以為每個進程獲取或獲取大約2-3 GB的可尋址內存(取決於堆碎片等)。 )。

問題是:數據集為4 + GB,並且對它們運行DSP算法,這些算法實際上需要對文件進行隨機訪問。 指向從文件生成的對象的指針是在C#中處理的,但文件本身已加載到C ++(帶有P / Invoked)的內存中(具有部分內存映射系統)。 因此,我認為該解決方案並不像簡單地調整窗口以訪問需要訪問的文件部分那樣簡單,因為從本質上講,我仍然希望將整個文件抽象為單個指針,從中可以調用方法訪問文件中幾乎任何地方的數據。

顯然,大多數內存映射體系結構都依賴於將單個進程拆分為多個進程。因此,例如,我將使用3個進程訪問一個6 GB的文件,每個進程均擁有一個2 GB的文件窗口。 然后,我需要添加大量邏輯來從這些不同的窗口/進程中提取和重組數據。 VirtualAllocEx顯然提供了一種增加虛擬地址空間的方法,但是我仍然不確定是否這是最好的方法。

但是,比方說,我希望該程序像在64位系統上的單個64位處理一樣“輕松”地運行。 假設我不關心抖動,我只是希望能夠操縱系統上的一個大文件,即使在任何時候僅將500 MB加載到物理RAM中也是如此。 有什么方法可以獲得此功能,而不必手動編寫一些荒謬的手動存儲系統? 或者,是否有比我到目前為止結合SO和Internet更好的方法?

這就引出了一個次要問題:是否有一種方法可以限制該過程使用多少物理RAM? 例如,如果我想將進程限制為一次只能將500 MB加載到物理RAM中(同時將多GB文件分頁到磁盤上)?

對於這個漫長的問題,我感到抱歉,但是我覺得這似乎是對我在SO和整個網絡上發現的許多問題(只有部分答案)的總結。 我希望這是一個可以充實確定性答案(或至少某些利弊)的領域,並且我們都可以在此過程中學到一些寶貴的知識!

您可以編寫一個訪問器類,為它提供基地址和長度。 如果出現錯誤條件(超出范圍等),它將返回數據或引發異常(或者,否則您想通知錯誤條件)。

然后,任何時候需要讀取文件時,訪問器對象都可以在調用ReadFile()之前使用SetFilePointerEx() ReadFile() 然后,您可以將訪問器類傳遞給讀取文件時創建的任何對象的構造函數。 然后,對象使用訪問器類從文件中讀取數據。 然后,它將數據返回到對象的構造函數,后者將其解析為對象數據。

如果稍后可以編譯為64位,則可以更改(或擴展)訪問器類以從內存中讀取。

至於限制該進程使用的RAM的數量,這主要是確保A)沒有內存泄漏(尤其是淫穢的內存泄漏),以及B)銷毀當前不需要的對象。 即使您稍后需要它,但數據也不會改變……只要銷毀對象即可。 然后在需要時重新創建它,從而允許它從文件中重新讀取數據。

暫無
暫無

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

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