5

这似乎是一个非常普遍的问题,但我仍然没有找到明确的答案。

我可以访问运行 linux 的服务器,该服务器具有 16 GB 的 RAM 和 16 核(64 位)CPU(/proc/cpuinfo 给出“Intel(R) Xeon(R) CPU E5520 @ 2.27GHz”)。但是,内核是 32 位的(uname -m 给出 i686)。当然,我没有root访问权限,所以我无法更改。

我正在运行我编写的 C++ 程序,它执行一些需要大量内存的计算,所以我需要一个大堆 - 但是每当我尝试分配超过 2GB 的空间时,我都会得到一个 badalloc,尽管 ulimit 返回“无限”。为简单起见,假设我的程序是这样的:

#include <iostream>
#include <vector>

int main() {
    int i = 0;
    std::vector<std::vector<int> > vv;
    for (;;) {
        ++i;
        vv.resize(vv.size() + 1);
        std::vector<int>* v = &(vv.at(vv.size() - 1));
        v->resize(1024 * 1024 * 128);
        std::cout << i * 512 << " MB.\n";
    }
    return 0;
}

使用 g++(无标志)编译后,输出为:

512 MB.
1024 MB.
1536 MB.
2048 MB.
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted

据我了解,这是 32 位系统的限制,显然是因为 32 位指针只能容纳 2^32 个不同的地址(我是否正确假设如果我在同一台服务器上编译相同的程序,但该服务器运行64位内核,比程序可以分配超过2GB?)

这不是分配的内存是否连续的问题,如果我在示例程序中切片更薄,也会出现同样的问题,而在我的实际程序中,没有大块内存,只有很多小块。

所以我的问题是:有什么我能做的吗?我无法更改操作系统,但我当然可以修改我的源代码,使用不同的编译器选项等......但我确实需要超过 2GB 的内存,而且没有明显的方法来进一步优化算法程序使用。

如果答案是明确的“不”,那么知道这一点仍然很好。

谢谢,卢卡斯

4

2 回答 2

5

如果您一次需要所有内存,不,如果不更改为 64 位内核,真的没有办法做到这一点(是的,这将允许您在单个进程中分配更多内存)

也就是说,如果您不需要一次全部使用内存,而只是快速访问,则您始终可以将部分内存存储卸载到另一个进程。

例如,这可以通过将数据存储在另一个进程中来工作,并让您的进程在需要时将共享内存从该进程临时映射到自己的内存空间中。它仍将存储在内存中,但在切换内存范围时会有一些开销。开销是否可以接受取决于您的内存访问模式。

这不是一个非常直接的方法,但是如果不更改内核来为您提供 64 位地址空间,听起来您有点束手无策。

编辑:您可以通过重新配置内核将限制提高到 2GB 以上,但这仅意味着您将在那里达到硬限制。此外,这将需要 root 访问权限。

于 2013-02-08T10:56:37.517 回答
0

答案是明确的“不”。如果您无法更改操作系统,则无法提高限制。该限制适用于整个进程,显然没有单个分配可以超过每个进程的限制。

根据用于编译内核的选项,限制可能高于 2GB,但肯定会小于 4GB。但我猜重新编译内核也算作“改变操作系统”。

看到这个讨论

是的,在 64 位操作系统上,这个限制会消失。

于 2013-02-08T10:58:25.187 回答