Fortran 90中双精度数组的最大大小是多少?

4

抱歉,如果这不是正确的地方提问,请见谅。这不是关于编程的问题,而是一个技术问题。 我需要使用双精度的巨大二维向量数组进行工作,大约有1000万个。但是,在其他程序中,我在处理此类数组时遇到了内存问题。我的问题是双精度数组大小是否有某种限制。

我在Linux上工作,使用Intel双核,32位。 谢谢


你可能需要增加进程内存限制。请参考 ulimit - M. S. B.
2个回答

5
好的,我将解释一下为什么字节数量受限制,而不仅仅是元素数量。在数组索引期间,必须计算元素的地址。当然,它必须适合于C变量intptr_t。此外,字节数组的大小必须适合于C变量size_t。这些都是现代计算机上32位和64位程序上的32位或64位。同样也适用于程序可寻址的虚拟内存!以及操作系统和CPU可寻址的内存,尽管它们可能是64位的,即使程序是32位的。

这是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.

预料之中,数组的大小已经溢出,程序在索引变量溢出之前就崩溃了。这不是编译器特定的功能,但是有一个根本原因。


4
Fortran语言标准并未限制程序可以(尝试)声明或分配的数组大小。实际上,您可能会发现您的编译器将数组中元素的总数限制为2 ^ 31-12 ^ 63-1,具体取决于默认整数大小是32位还是64位。您可能会发现数组的任何维度的最大大小也受到相同值的限制。
实际上,您可以声明的数组的最大大小将受计算机可用的RAM的限制。由于双精度值占用8个字节,因此您可以相对容易地计算出您可能能够处理的数组的最大范围。与您想要处理的数据量相比,所需的任何存储开销都非常小。
回应VladimirF的评论:
- 我指的是元素数,而不是字节数。正是元素数量确定了访问数组元素所需的最大索引值。 - 某些编译器可能会强制限制单个数组中使用的字节数,但这不是我要表达的观点。 - Fortran数组当然可以从0开始索引,事实上,可以从范围内的任何正整数或负整数开始索引,但这真的只是方便程序员的一种方式。

我认为字节数必须是2^31-1或2^63-1,而不是元素数量。 - Vladimir F Героям слава
因为数组不能有地址0,所以要小于。 - Vladimir F Героям слава
你的程序可以使用的内存空间是有限制的,只能是可用的RAM大小减去程序和分页文件的大小。由于程序也需要被加载到内存中,因此如果程序越大,那么数据所占用的空间就会越小,除非你使用覆盖技术。我并没有调查现代编译器/链接器是否可以处理覆盖技术,因为它们大多运行在具有动态页面分配功能的操作系统上。 - cup
我所说的地址0当然是指空指针,而不是零数组索引。 - Vladimir F Героям слава
抱歉,实际上错误信息是“分段错误(核心已转储)”。我曾经认为Linux会动态分配内存,但现在不确定了,也许需要手动设置。因此,M.S.B.提出的建议是相关的。 - JoeCoolman
显示剩余2条评论

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