2

我正在尝试在我的笔记本电脑上运行一个模拟程序(Linux 3.8.0-25-generic x86_64,带有 Ubuntu 13.04)。

它可以编译,但是当分配一些数组大小时,我得到:

forrtl:严重(179):无法分配数组 - 数组大小计算溢出。\

关于这条消息的一些谷歌搜索让我得出结论,这是因为我的程序内存不足而生成的。

为了检查这个假设,我尝试为同一个数组分配一个较小的维度,但仍然遇到同样的问题。

我接下来尝试的是增加堆栈内存,但仍然遇到同样的问题。

这是代码:

program memoria

implicit none

integer :: n,num
complex, dimension(:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:,:), allocatable :: ddptrj

n=4

num=21


allocate(ddptrj(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,num))

deallocate(ddptrj)


endprogram memoria

我怎么解决这个问题?

4

2 回答 2

2

Fortran 2008 标准定义了最大等级 15ifort 允许 31 . 截至 2013 年 5 月gfortran,仍然不支持超过 7 个维度。所以 - 如果你真的需要所有 22 维,请使用- 但请注意,此功能是标准的扩展,其他编译器可能不会编译你的代码。ifort

编辑:总结评论中的讨论:

有两个问题 - 一个与最大维度有关,另一个与数组大小有关。

对于不允许 22 维的编译器,可以使用一个包含所有元素的秩为 1 的大型数组,并使用 strides 自己计算元素内部的索引。

在内部,所有数组都连续存储在内存中 - 可以将其视为一个等级为 1 且大小为 N*M* 的大型数组...... Fortran 实际上以列优先格式存储结果数组。所以一个矩阵 Z(NxM) 被存储为一个向量 A(N*M),并且对元素的访问是通过 strides 计算的: Z(3,4) 在索引 A( M*(4-1)+3 ) . 请注意,两个数组的内存是相同的!

下一个问题是数组大小:

对于 n=2,代码有效,因为它适合内存: 2**21*21=44040192 at complex(16 字节)这相当于 672 MB。在 n=4 时,这变为 4**21*21,即 1344TB。

于 2013-09-15T16:06:17.123 回答
0

如果您使用的方法需要 22 维,那么您几乎肯定需要更改算法。正如人们在其他地方所指出的那样,您不仅会使用大量内存,而且如果您想对该数组中的所有元素执行某些操作,运行时本身也会变得绝对巨大。

因为您使用的是 Fortran,所以我的猜测是您正在查看某种具有 22 维的参数空间,并记录每个参数组合的拟合优度或可能性。在这种情况下,您应该考虑使用其他算法(例如 MCMC)来探索空间。

但这只是一个猜测——如果你告诉我们你试图解决什么潜在的问题,人们可能会有更多的建议。

于 2013-09-17T07:52:20.573 回答