繁体   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