【发布时间】:2013-08-07 18:33:36
【问题描述】:
我在这行 MATLAB 代码中遇到内存不足错误:
result = (A(1:xmax,1:ymax,1:zmax) .* B(2:xmax+1,2:ymax+1,2:zmax+1) +
A(2:xmax+1,2:ymax+1,2:zmax+1) .* B(1:xmax,1:ymax,1:zmax)) ./ C
其中 C 是另一个数组。这是在 32 位 MATLAB 上(我目前似乎无法获得 64 位版本,这将暂时解决我的问题)。
数组结果 A、B 和 C 是预先初始化的并且永远不会改变大小。然后我猜这个计算不是在恒定空间中执行的。
这是正确的吗?有没有办法让它运行或检查它是否在恒定空间中运行?
这些数组的大小约为(250、250、250)。
如果 MATLAB 不以恒定大小运行它,是否有人对 Octave 或 Julia 或(插入类似语言)是否有任何经验?
编辑 1:
我消除了多余的数组。有 10 个 258 x 258 x 338 的阵列,对应 1.67 GB。还有很多其他变量,但它们要小得多。给出的计算是简化的,计算的形式是:
R = (A(3Drange) .* B(3Drange) + A(new_3Drange) .* D(new_3Drange) + . . . ) ./ C
范围通常仅相差正负 1 或 2。
内存命令的输出:
Maximum possible array: 669 MB (7.013e+08 bytes) *
Memory available for all arrays: 1541 MB (1.616e+09 bytes) **
Memory used by MATLAB: 2209 MB (2.316e+09 bytes)
Physical Memory (RAM): 8154 MB (8.550e+09 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
显然我应该违反第二行。但是,代码运行良好,直到我对数组实际执行的第一个操作。也许 MATLAB 在我输入时很懒惰并且没有分配:
A=zeros(xmax+2,ymax+2,zmax+2);
但仍然在工作区告诉我变量已分配。
此代码以前曾用于较小的数组。 (编辑:但似乎实际内存大小是问题,而不是每个单独数组的大小)。
让我非常好奇的是为什么它在分配时没有出错,而是在第一次计算时出错。
编辑 2:
我已经确认循环在空间中运行不恒定。在计算过程中分配了大约 0.8 GB 的内存。这是循环执行命令时资源使用情况的图像:
但是,我尝试将计算分解为多行。我在每次添加时拆分计算并在新命令中添加每个部分,将R 视为累加器。结果是一次分配的内存更少,但可能更频繁。图片如下:
我仍然很好奇为什么 MATLAB 不想在恒定空间中执行它。我认为这可能与索引被转移有关 - 我计划稍后对其进行更多调查,然后将所有这些放在一起作为答案,但有人可能会击败我,这也很棒。不过,现在我可以运行我正在寻找的数组大小并完成我的项目。
【问题讨论】:
-
是什么让您认为它不是在恒定空间中运行的?
-
看看能不能预分配
result。这至少会看看一切是否合适。 -
尝试分配您的重复变量,例如
1:xmax、a=1:xmax、A(a,b,c).*B(a+1,b+1,c+1) + A(a+1,b+1,c+1) .*B(a,b,c))./C -
double的 250x250x250 数组应该只有 125MB 左右。其中三个是375MB;包括一个临时和一个结果的空间将其增加到 625MB。这对于 MATLAB 来说应该很容易处理,除非你有一大堆其他数组。当这三个数组是工作区中唯一的变量时,尝试运行计算。 -
为什么不执行常量空间?因为内存分配速度很快,而且他们不再围绕仍在使用旧 32 位计算机/操作系统/版本的人进行设计。如今,对于 Matlab 所做的许多事情,使用内存几乎总是比使用 CPU 快。阅读更多here。