我们有一个32位地址空间的进程,它需要访问比直接寻址更多的内存。此进程的大部分源代码都无法更改。我们可以更改用于管理数据访问的模块。到这些模块的接口可以包括标识要访问的存储器的64位数据。
我们目前有一种实现方式,其中接口模块使用与64位进程的进程间通信来将数据传输到该64位进程中的地址空间和从该地址空间传输数据。
有更好的方法吗?
很少有平台支持混合使用32位和64位代码。如果您需要超过2或3 GB的地址空间,您的选择是:
-
将整个应用程序重新编译为64位或
-
使用内存映射文件对大块数据进行分页。
重新编译很容易。在32位程序中访问超过2或3 GB的内存是非常困难的。
请注意,将32位应用程序重新编译为64位应用程序不需要更改代码或功能,除非您的代码具有不可移植的结构,否则可能会出现一些错误。比如:
size_t round_to_16(size_t x)
{
return x & ~15; // BUG in 64-bit code, should be ~(size_t) 15
}
如各种评论所述,情况是:
- 有一个32位进程,其中一小部分可以更改。其余部分基本上是预先编译的,不能更改
- 小部分当前与64位进程通信,以在64位地址空间和32位进程的地址空间之间传输所选数据
- 您可能会寻求性能更高的替代方案
进程间通信通常很快。可能没有更快的方法,除非:
- 您的系统具有用于加速内存传输的专用硬件,或者
- 您的系统具有重新映射内存的方法(详细信息请参阅下文)
Unix有shmat
和mmap
这样的调用,允许进程连接到共享内存段,并将其地址空间的一部分映射到共享内存分段内的偏移量。这样的调用可能支持将32位地址空间的部分映射到存在于大物理地址空间中的大共享内存段中。
例如,调用mmap
采用void *
参数作为要在进程地址空间中映射的地址,并采用off_t
参数作为偏移量作为共享内存段。可以设想,即使void *
仅是32位指针,off_t
类型也可以是64位类型。我没有对此进行调查。
可以想象,重新映射内存比通过复制操作传输内存更快,因为它可以简单地更改虚拟地址映射,而不是物理地移动数据。