【发布时间】:2013-11-05 03:58:42
【问题描述】:
对不起,如果这不是做这个问题的正确地方,这不是关于编程而是一个技术问题。 我需要以双精度处理巨大的二维向量数组,其中大约有 1000 万个。但是,在其他程序中,我在处理这种数组时遇到了内存问题。我的问题是双精度数组大小是否有某种限制。
我在 Linux、Intel 两核 32 位工作。 谢谢
【问题讨论】:
-
您可能需要增加您的进程内存限制。见
ulimit。
对不起,如果这不是做这个问题的正确地方,这不是关于编程而是一个技术问题。 我需要以双精度处理巨大的二维向量数组,其中大约有 1000 万个。但是,在其他程序中,我在处理这种数组时遇到了内存问题。我的问题是双精度数组大小是否有某种限制。
我在 Linux、Intel 两核 32 位工作。 谢谢
【问题讨论】:
ulimit。
好的,我将解释为什么字节数是有限的,而不仅仅是元素数。在数组索引期间,必须计算元素的地址。当然它必须适合intptr_t C 变量。此外,以字节为单位的数组大小必须适合size_t C 变量。这些都是 32 位或 64 位的 32 位和现代机器上的 64 位程序。程序可寻址的虚拟内存也是如此!还有操作系统和 CPU 可寻址的内存,即使程序是 32 位,它们也可以是 64 位。
这是 32 位程序和操作系统无法寻址超过 4 GB 内存的根本原因。即使您可以使用比所选 CPU 字长更宽的 Fortran 变量以某种方式计算地址,CPU 也无法访问它。
最后我在 Intel Fortran 中进行了 32 位模式下的实验,其中包含 32 字节元素的数组:
complex(16), allocatable :: a(:)
do i=1,100
allocate(a(2**i))
a(size(a)) = 1
deallocate(a)
write(*,*) i
end do
end
ifort arraysize.f90 -m32 -check -traceback -g
输出如预期:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
forrtl: severe (179): Cannot allocate array - overflow on array size calculation.
正如预期的那样,数组的大小以字节为单位溢出,程序在索引变量溢出之前很久就崩溃了。这不是编译器特有的功能,但这是有根本原因的。
【讨论】:
Fortran 语言标准没有定义程序可以(尝试)声明或分配的数组大小的限制。在实践中,您可能会发现您的编译器将数组中的元素总数限制为2^31-1 或2^63-1,具体取决于您的默认整数大小是32 位还是64 位。您可能会发现数组的任何维度的最大大小也被限制为相同的值。
实际上,您可以声明的最大数组大小将受到计算机上可用 RAM 的限制。由于双精度值占用 8 个字节,因此计算可能能够使用的数组的最大边界相对容易。与您似乎想要处理的数据量相比,阵列所需的任何存储开销都是很小的。
回应 VladimirF 的 cmets
0 开始索引,实际上可以从范围内的任何正整数或负整数开始索引,但这实际上只是为了方便程序员。【讨论】: