【问题标题】:what is the biggest array size for double precision in Fortran 90?Fortran 90 中双精度的最大数组大小是多少?
【发布时间】:2013-11-05 03:58:42
【问题描述】:

对不起,如果这不是做这个问题的正确地方,这不是关于编程而是一个技术问题。 我需要以双精度处理巨大的二维向量数组,其中大约有 1000 万个。但是,在其他程序中,我在处理这种数组时遇到了内存问题。我的问题是双精度数组大小是否有某种限制。

我在 Linux、Intel 两核 32 位工作。 谢谢

【问题讨论】:

  • 您可能需要增加您的进程内存限制。见ulimit

标签: arrays fortran fortran90


【解决方案1】:

好的,我将解释为什么字节数是有限的,而不仅仅是元素数。在数组索引期间,必须计算元素的地址。当然它必须适合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.

正如预期的那样,数组的大小以字节为单位溢出,程序在索引变量溢出之前很久就崩溃了。这不是编译器特有的功能,但这是有根本原因的。

【讨论】:

    【解决方案2】:

    Fortran 语言标准没有定义程序可以(尝试)声明或分配的数组大小的限制。在实践中,您可能会发现您的编译器将数组中的元素总数限制为2^31-12^63-1,具体取决于您的默认整数大小是32 位还是64 位。您可能会发现数组的任何维度的最大大小也被限制为相同的值。

    实际上,您可以声明的最大数组大小将受到计算机上可用 RAM 的限制。由于双精度值占用 8 个字节,因此计算可能能够使用的数组的最大边界相对容易。与您似乎想要处理的数据量相比,阵列所需的任何存储开销都是很小的。

    回应 VladimirF 的 cmets

    • 我的意思是,并且仍然是指元素的数量,而不是字节的数量。元素的数量决定了访问数组元素所需的最大索引值。
    • 可能是某些编译器对单个数组中使用的字节数施加了限制,但这不是我要说的重点。
    • 当然,Fortran 数组可以从0 开始索引,实际上可以从范围内的任何正整数或负整数开始索引,但这实际上只是为了方便程序员。

    【讨论】:

    • 我认为字节数必须是 2^31-1 或 2^63-1,而不是元素数。
    • 或者更少,因为数组不能有地址0。
    • 我的 RAM 有 2.5 Gb,所以如果我的 RAM 专门用于执行我的程序,那么我在处理具有我所说的大小的数组时不会有问题。但它已经发生了程序已经停止,出现“故障内存存储开销”或类似的消息错误。那么,我是否在执行期间关闭了除 FORTRAN 之外的任何其他程序?
    • 您受到 RAM 量减去程序大小和分页文件大小的限制。您的程序也需要加载到内存中,因此程序越大,用于数据的空间就越少;也就是说,除非你覆盖它。我没有调查现代编译器/链接器是否可以处理覆盖,因为它们中的大多数运行在具有动态页面分配的操作系统上。
    • 地址 0 我当然是指 NULL 指针,而不是零数组索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 2021-11-06
    • 1970-01-01
    • 2011-09-03
    • 1970-01-01
    相关资源
    最近更新 更多