Memory management 内存不足
我正在尝试运行以下程序,该程序计算系数仅为+1或-1的d次多项式的根,然后将其存储到文件中Memory management 内存不足,memory-management,memory-leaks,wolfram-mathematica,Memory Management,Memory Leaks,Wolfram Mathematica,我正在尝试运行以下程序,该程序计算系数仅为+1或-1的d次多项式的根,然后将其存储到文件中 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]=-z2-z-1 f[z,2]=-z2-z+1 f[z,3]=-z2+z-1 f[z,4]=-z2+z+1 Distr
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]=-z2-z-1f[z,2]=-z2-z+1
f[z,3]=-z2+z-1
f[z,4]=-z2+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中的内存使用量逐渐增加,直到它填满所有内存(本机上为6GB);然后计算继续得非常慢;为什么会这样
我不确定是什么消耗了内存-我唯一的猜测是文件流消耗了内存,但事实并非如此:我尝试将数据附加到2GB文件中,但没有明显的内存使用情况。Mathematica似乎完全没有理由在这里使用大量内存
对于较小的d值(例如15),行为如下:我有4个内核在运行。当它们都通过ParallelDo循环(每个循环一次执行一个j值)时,内存使用会增加,直到它们都完成该循环一次。下一次他们通过这个循环时,内存使用根本不会增加。计算最终结束,一切都很好
同样,非常重要的是,一旦计算停止,内存使用不会下降。
如果我开始另一次计算,会发生以下情况:
-如果上一次计算在内存使用仍在增加时停止,它将继续增加(可能需要一段时间才能再次开始增加,基本上要达到计算中的相同点)
-如果以前的计算在内存使用没有增加时停止,则不会进一步增加
编辑:问题似乎来自f的相对复杂性-将其更改为更简单的多项式似乎可以解决问题。我想问题可能是Mathematica会记住f[z,I]的特定值,但设置f[z,I]:=。就在计算了f[z]的根之后,i]抱怨说赋值一开始就不存在,内存仍然在使用
这真的很令人费解,因为f是我能想象的唯一剩下的占用内存的东西,但在内部Do循环中定义f并在每次计算根后清除它并不能解决问题。哎哟,这是一个令人讨厌的问题 现在的情况是,
N
将缓存结果,以便在以后需要时加快计算速度。有时这绝对是你想要的,但有时它只是打破了世界。幸运的是,您确实有一些选择。一种是使用命令,它只执行tin上的命令。在我运行您的非并行循环一段时间后(在感到厌烦并中止计算之前),MemoryInUse
报告使用了~160个MiB。使用ClearSystemCache将其压缩到大约14个MiB
您应该注意的一件事是使用更改缓存行为,而不是以编程方式调用ClearSystemCache
。您应该查看SystemOptions[“CacheOptions”]
以了解可能性
编辑:缓存会给更复杂的表达式带来更大的问题,这并不奇怪。它必须将这些表达式的副本存放在某个地方,而更复杂的表达式需要更多内存。您是否尝试过用更小的、甚至是单个的d值来运行此算法?我怀疑我是否能够重现这一点,因为我使用的是Mathematica 6.0—您没有任何多核并行支持。然而,我知道Mathematica有一个习惯,就是在记忆中保留很多你认为会消失的东西。您是否尝试过将
模块
放在ParallelDo
和Do
之间,使{root,a,b,stm}
成为本地的?很有趣。我试着用两个内核运行它(没有IO的东西),内存使用情况非常糟糕,直到我感到厌烦并放弃它。我发现模块
即使在并行情况下也没有什么不同。但是,为了将来的参考,您需要将模块
放在内部Do
中。我使代码更清晰了-内存使用的唯一来源是使用N[Root[]函数,但我不知道如何修复它。在这之后清除[root,a,b]并不能解决问题。嗯,我复制你的结果有困难。目前,出现了两个问题:在未调用的版本中,当我调用ClearSystemCache时,MemoryUse确实报告正在使用的内存已经减少,但任务管理器显示内核仍在使用同样多的内存。其次,在并行模式下,我找不到清除单个内核缓存的选项。但是你似乎已经找到了确切的原因,现在更重要的是找到如何处理它。弄乱缓存选项也没有效果-我将所有设置都设置为false,将最大字节大小设置为0,这没有任何区别(对于未并行化版本,因此对于并行化版本也没有区别)。好的,添加ClearSystemCache实际上是可行的;出于某种原因,它第一次不起作用,但现在起作用了。它甚至可以在并行版本中工作。谢谢