Mathematica耗尽内存

时间:2009-10-28 17:12:09

标签: memory-management memory-leaks wolfram-mathematica

我正在尝试运行以下程序,该程序计算度数达到d的多项式的根,系数仅为+1或-1,然后将其存储到文件中。

d = 20; n = 18000; 
f[z_, i_] := Sum[(2 Mod[Floor[(i - 1)/2^k], 2] - 1) z^(d - k), {k, 0, d}];

这里f [z,i]给出z中的多项式,其中加号或减号以二进制计数。说d = 2,我们会有

f [z,1] = -z 2 - z - 1
f [z,2] = -z 2 - z + 1
f [z,3] = -z 2 + z - 1
f [z,4] = -z 2 + z + 1

DistributeDefinitions[d, n, f]

ParallelDo[ 
            Do[ 
                     root = N[Root[f[z, i], j]];
                     {a, b} = Round[n ({Re[root], Im[root]}/1.5 + 1)/2];
            {i, 1, 2^d}],
{j, 1, d}]

我意识到阅读这可能不太令人愉快,但无论如何它都相对较短。我会尝试减少相关部分,但在这里我真的不知道问题是什么。我正在计算f [z,i]的所有根,然后围绕它们使它们对应于n×n网格中的点,并将该数据保存在各种文件中。

出于某种原因,Mathematica中的内存使用率会逐渐增加,直到它填满所有内存(此机器上为6 GB);然后计算继续非常缓慢;这是为什么?

我不确定这里的内存消耗是多少 - 我唯一的猜测就是内存消耗的文件流,但事实并非如此:我尝试将数据附加到2GB文件中,没有明显的内存使用情况。似乎Mathematica绝对没有理由在这里使用大量内存。

对于d的小值(例如15),行为如下:我有4个内核在运行。当它们都通过ParallelDo循环(每次都执行j值)时,内存使用会增加,直到它们都完成一次循环。然后,下次他们经历该循环时,内存使用根本不会增加。计算最终完成,一切都很好。

另外,非常重要的是,一旦计算停止,内存使用不会再次下降。 如果我开始另一个计算,会发生以下情况:

- 如果先前的计算在内存使用仍在增加时停止,它会继续增加(可能需要一段时间才能再次开始增加,基本上是为了达到计算中的相同点)。

- 如果先前的计算在内存使用未增加时停止,则不会进一步增加。

编辑这个问题似乎来自f的相对复杂性 - 将其更改为更简单的多项式似乎可以解决问题。我认为问题可能是Mathematica记住f [z,i]的特定值i,但设置f [z,i]:=。在计算了f [z,i]的根之后,抱怨首先不存在赋值,并且仍然使用了内存。

真的很令人费解,因为f是我能想象的唯一剩余内存,但是在内部Do循环中定义f并在每次计算根之后清除它并不能解决问题。

1 个答案:

答案 0 :(得分:11)

哎呀,这是一个令人讨厌的问题。

正在发生的事情是N会对结果进行缓存,以便在您再次需要时加快未来的计算速度。有时这绝对是你想要的,但有时它只是打破了世界。幸运的是,你确实有一些选择。一种是使用ClearSystemCache命令,它就像它在锡上说的那样。在我运行你的非并行化循环一段时间之后(在厌倦并中止计算之前),MemoryInUse报告使用了~160 MiB。使用ClearSystemCache可以降低到大约14 MiB。

您应该看一下,而不是以编程方式调用ClearSystemCache,而是使用SetSystemOptions来更改缓存行为。您应该查看SystemOptions["CacheOptions"]以了解可能性。

编辑:缓存会给更复杂的表达式带来更大的问题,这并不奇怪。它必须在某处隐藏这些表达式的副本,而更复杂的表达式需要更多的内存。