具有 32 位地址空间的进程如何有效地访问大量内存?[复制]

How can a process with a 32-bit address space access large amounts of memory efficiently? [duplicate]

提问人:kharevbv 提问时间:8/1/2013 最后编辑:Eric Postpischilkharevbv 更新时间:8/1/2013 访问量:282

问:

我们有一个具有 32 位地址空间的进程,该进程需要访问的内存多于可直接寻址的内存。此过程的大多数源代码都无法更改。我们可以更改用于管理数据访问的模块。这些模块的接口可以包括标识要访问的内存的 64 位数据片段。

我们目前有一个实现,其中接口模块使用与 64 位进程的进程间通信来传输数据,并在该 64 位进程的地址空间之间传输数据。

有没有更好的方法?

c

评论

1赞 WhozCraig 8/1/2013
所以。。您希望 32 位应用程序能够访问 64 位地址空间?呃......您不只制作 64 位应用程序的任何原因?
0赞 Hot Licks 8/1/2013
你需要重新表述你的问题。目前尚不清楚您是在谈论 32 位和 64 位寻址模型之间的代码可移植性,还是以某种方式认为使用 64 位模型允许您在 32 位空间中寻址更多。
0赞 Hot Licks 8/1/2013
或者您是否希望以某种方式实现分页/覆盖系统,以便以某种方式从 1G 空间获得更多的“可寻址性”?要做到这一点,你需要跳出普通的指针,使用兴奋剂向量或类似的东西。
0赞 kharevbv 8/1/2013
@WhozCraig您正确理解了我的问题,我无法制作一个 64 位应用程序,这是一个限制,您是否看到一些仅在 32 位空间中执行此操作的方法
0赞 kharevbv 8/1/2013
@HotLicks我说的是 32 位和 64 位寻址模型之间的代码可移植性

答:

3赞 Dietrich Epp 8/1/2013 #1

很少有平台支持混合 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
}

评论

0赞 kharevbv 8/1/2013
重新编译不是一种选择,我在那里受到限制,我需要找到其他解决方案
0赞 Dietrich Epp 8/1/2013
如果我不明白,请原谅我,但如果你不能重新编译,那你应该怎么做?
0赞 kharevbv 8/1/2013
看到这是一个大代码的小模块,所以在64位应用程序中重新编译整个代码是不可行的,我需要一些替代解决方案
0赞 Dietrich Epp 8/1/2013
如果数据不适合应用程序的地址空间,请将数据存储在数据库中。不能在 32 位应用程序中运行 64 位模块。(我的意思是,这在理论上是可能的,但你做不到。
1赞 Dietrich Epp 8/1/2013
这很好,但你说的是两个不同的应用程序。每个应用程序都是 32 位或 64 位。你不能混合。
1赞 Eric Postpischil 8/1/2013 #2

如各种评论所述,情况是:

  • 有一个 32 位进程,其中一小部分可以更改。其余的基本上是预编译的,不能更改。
  • 一小部分当前与 64 位进程通信,以在 64 位地址空间和 32 位进程的地址空间之间传输选定的数据。
  • 您寻求替代方案,可能具有更高的性能。

进程间通信通常很快。可能没有更快的方法,除非:

  • 您的系统具有用于加速内存传输的专用硬件,或者
  • 您的系统具有重新映射内存的方法(详见下文)。

Unix 具有 and 等调用,允许进程附加到共享内存段,并将其地址空间的一部分映射到共享内存段内的偏移量。此类调用可能支持将 32 位地址空间的一部分映射到大型物理地址空间中存在的大型共享内存段。shmatmmap

例如,调用采用要映射到进程地址空间的地址的参数,以及将偏移量映射到共享内存段的参数。可以想象,即使 32 位指针,该类型也可能是 64 位类型。我没有对此进行调查。mmapvoid *off_toff_tvoid *

重新映射内存比通过复制操作传输内存要快,因为它可能涉及简单地更改虚拟地址映射,而不是物理移动数据。

评论

0赞 Dietrich Epp 8/1/2013
在 Linux 上,您可以定义和使用 64 位版本的函数(例如),也可以定义和使用函数的常规版本。_LARGEFILE_SOURCEmmap64_FILE_OFFSET_BITS=64
0赞 kharevbv 8/1/2013
感谢您的回答,我将阅读更多关于 mmap :)