Memory management 内存不足

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

我正在尝试运行以下程序,该程序计算系数仅为+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

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实际上是可行的;出于某种原因,它第一次不起作用,但现在起作用了。它甚至可以在并行版本中工作。谢谢