如何为您的程序(GCC)分配更多内存

5
我想给程序分配更多的内存,有哪些gcc标志可以实现这一点?
顺便提一下,我试图创建一个非常大的矩阵(真的很大),稍后将对其进行压缩算法处理。因此,我无法避免创建这样一个大的矩阵来存储数据。

2
真正的大有多大?100 x 100?1000 x 1000?10,000 x 10,000? - JeremyP
@JeremyP:没有必要用讽刺的口气回答。这个问题在Stack Overflow搜索中排名很高。如果不确定,就以最具挑战性的方式解释问题,例如分配95%的物理内存,即60GB。 - P Marecki
@PMarecki 我的评论并没有任何讽刺意味。"really large" 真的没有为我们提供提问者遇到的问题的任何概念。例如,它可能只是“栈溢出过大”或者可能是“可用内存过小”的问题,或者其他定义的“太大”。在每种情况下,答案都是不同的。最具挑战性的方式可能是对于物理RAM来说过大了,如果提问者只是在栈上分配了数组而导致堆栈溢出,那么答案就会是错误的。 - JeremyP
4个回答

4

您的问题不太清楚,但我猜测您正在尝试创建一个大型的多维数组(矩阵)作为某个函数(可能是主函数)的本地变量(自动变量),但这似乎失败了。

int foo(int boo, int doo) {
    int big_array[REALLY_BIG];
    ...

这将失败,因为C编译器试图在程序系统栈上为此类变量腾出空间。编译器可能会在尝试思考这种大型堆栈变量时失败(特别是由于可能使其更大的对齐问题),或者它可能生成代码尝试执行此操作,但是CPU无法运行它,因为栈指针相对索引受到限制,或者因为操作系统已经限制了程序系统栈的大小。
也许有改变操作系统限制的方法,但如果是CPU限制,您只能以不同的方式处理。
对于某些内容,最简单的方法是使用全局变量或静态变量来存储这样的大型数据。这样做可以在编译时或在程序加载时(即运行时间之前)为数据分配空间,但会限制您具有多个副本的能力,因为您必须提前规划声明足够的全局变量来容纳您想要同时处于“活动”状态下的所有内容。
您还可以尝试使用malloc或calloc为您分配内存。
第三个选项(如果您正在使用*nix系统)是对包含矩阵的文件进行内存映射。请查看mmap系统调用。
使用mmap、static或全局变量的另一个好处是,在大多数操作系统下,虚拟内存管理器可以将原始文件(包含mmap矩阵的文件,或静态或全局可执行文件)用作数据使用的交换空间。这使得您的程序可以在不对物理内存或虚拟内存管理器施加太大压力的情况下运行。

4
如果矩阵非常大,您可能需要在较小的段中分配内存,以便可以在虚拟内存空间中找到空间。在32位Windows上,我发现您无法在单个分配中获得超过约980 MB的任何内容。在Linux上,尝试获得超过约1.5 GB的内容是有风险的。
在64位系统中,您可以获得更多的内容。
但无论如何,我建议使用可以为您处理内存和算法的矩阵库。有许多微妙的技巧可以使矩阵计算更快。线程技巧、以缓存大小块计算、预取数据、SSE向量操作等等。
您可能想考虑使用英特尔或AMD的数学库。

从32位Windows的角度来看,您可以直接使用VirtualAlloc来实现更好的效果。尽管在提交内存时,您的进程仍然受到2GB保留内存的限制,请参阅http://blogs.msdn.com/b/slavao/archive/2005/01/27/361678.aspx以获取这些令人兴奋的详细信息。 - Chris O
Intel IPP产品包含适用于Windows和Linux的数学库,http://software.intel.com/en-us/intel-ipp/。 - Chris O
@Chris O:最近我一直试图在32位Windows中获得可靠的1GB分配。VirtualAlloc将无法做到。 - Zan Lynx
我可以很容易地做到这一点,但只是从一个小的测试应用程序中尝试了大量分配,这可能比从实际应用程序中更有机会。 - Chris O

3

您不需要任何特殊的gcc标志。

使用malloc在运行时动态分配数组。

如果您不得不使用静态数组,或者如果您的环境默认设置限制了程序对虚拟内存的访问,那么您可能需要使用ulimit命令。

ulimit -v unlimited
ulimit -d unlimited

否则,您需要更清楚地指明阻止您获得足够内存的错误,并且可能还要告诉我们您的矩阵有多大。

2
使用堆!malloc()等函数是你的好朋友。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接