Wolfram mathematica 应用vs映射的内存使用。虚拟内存使用和锁定
我需要在一个长长的成对列表中找到所有成对数字的总和。在Mathematica中有很多方法可以做到这一点,但我正在考虑使用Wolfram mathematica 应用vs映射的内存使用。虚拟内存使用和锁定,wolfram-mathematica,memory-management,Wolfram Mathematica,Memory Management,我需要在一个长长的成对列表中找到所有成对数字的总和。在Mathematica中有很多方法可以做到这一点,但我正在考虑使用Plus或Total。由于Total在列表上工作,Map是在列表中使用的函数式编程工具,而Apply在级别1(@@@)是用于Plus的工具,因为Plus将要添加的数字作为参数 下面是一些演示代码(警告:在执行此操作之前保存所有工作!): 您可能已经注意到,我在Plus的代码中添加了timeconstraint。这是我为您提供的一项保护措施,因为赤裸裸的代码让我的电脑几乎崩溃。事
Plus
或Total
。由于Total
在列表上工作,Map
是在列表中使用的函数式编程工具,而Apply
在级别1(@@@)是用于Plus
的工具,因为Plus
将要添加的数字作为参数
下面是一些演示代码(警告:在执行此操作之前保存所有工作!):
您可能已经注意到,我在Plus
的代码中添加了timeconstraint
。这是我为您提供的一项保护措施,因为赤裸裸的代码让我的电脑几乎崩溃。事实上,上面的代码对我有效,但如果我将第一行的范围增加到7000,我的计算机就会锁定,再也回不来了。什么都不起作用,没有alt周期,程序切换,ctrl-alt-delete,尝试使用任务栏启动process manager,关闭笔记本电脑盖让其睡眠,等等,实际上什么都没有
该问题是由Plus@@@pairs
行的极端内存使用造成的。虽然“pairs”本身占用了大约288MB的空间,而列表中的数据总量占了其中的一半,但加号线的计算速度很快就消耗了大约7GB。这是我可用物理内存的结束,任何较大的内存都会导致磁盘上使用虚拟内存。而Mathematica和/或Windows显然在使用虚拟内存时表现不佳(顺便说一句,MacOS和Linux是否表现更好?)。相反,总行对内存使用图没有明显的影响
我有两个问题:
Plus
和Total
之间的等效性(“Total[list]相当于Apply[Plus,list]”),如何解释行为上的极端差异?我认为这与Apply
和Map
之间的差异有关,但我对所涉及的内部机制感到好奇MemoryConstrained
来限制命令的内存占用,但在怀疑Mathematica可能占用您所有系统资源的任何地方都必须使用它,这是一种痛苦。是否有一个全局设置,我可以用来告诉Mathematica对其所有操作只使用物理内存(或者,最好是其中的一部分)?这将是非常有帮助的,因为在过去的几周里,这种行为已经导致了一些锁死事件,而且它真的开始让我恼火Plus@@@pairs
正在解包:
In[11]:= On["Packing"]
In[12]:= pairs=Tuples[Range[6000],{2}];
In[13]:= TimeConstrained[Plus@@@pairs;//Timing,30]
During evaluation of In[13]:= Developer`FromPackedArray::punpack1: Unpacking array with dimensions {36000000,2}. >>
Out[13]= $Aborted
这将做同样的事情,并且不会解包,这意味着它使用更少的内存
On["Packing"]
pairs=Tuples[Range[6000],{2}];
a = pairs[[All, 1]];b=pairs[[All, 2]];
Plus[a, b];
您可以在此处阅读Mathematica中有关包装的更多信息:
我只想补充一些观察结果,这些观察结果可能会进一步澄清情况。正如@Joshua在回答中指出的(另请参见类似讨论的评论),效率低下的原因与拆包有关。我的猜测是
Apply
解包的一般原因是编译器(Compile
)对Apply
的支持非常有限,也就是说,只能使用3个头-List
、Plus
和Times
。因此,在SystemOptions[“CompileOptions”]
中,我们可以看到Apply
的编译长度被设置为无穷大-通常甚至尝试自动编译Apply
都没有意义。然后,当编译长度大于实际数组维度时,它可能会解包。当我们将“ApplyCompileLength”
设置为有限长度时,行为会发生变化:
On["Packing"]
pairs=Tuples[Range[2000],{2}];
SetSystemOptions["CompileOptions"->"ApplyCompileLength"->100];
TimeConstrained[Plus@@@pairs;//Timing,30]
{0.594,Null}
再次将其更改回可恢复观察到的初始行为:
In[34]:=
SetSystemOptions["CompileOptions" -> "ApplyCompileLength" -> Infinity];
TimeConstrained[Plus @@@ pairs; // Timing, 30]
During evaluation of In[34]:= Developer`FromPackedArray::punpack1: Unpacking
array with dimensions {4000000,2}. >>
Out[35]= {2.094, Null}
关于你的第二个问题:也许,约束内存的系统方法与@Alexey Popkov所做的一样,使用主内核控制从内核,一旦内存不足,从内核就会重新启动。我可以提供一个远没有那么复杂的黑客,但可能仍然有一些用处。以下函数
ClearAll[totalMemoryConstrained];
SetAttributes[totalMemoryConstrained, HoldRest];
Module[{memException},
totalMemoryConstrained[max_, body_, failexpr_] :=
Catch[MemoryConstrained[body,
Evaluate[
If[# < 0, Throw[failexpr, memException], #] &@(max -
MemoryInUse[])], failexpr], memException]];
ClearAll[totalMemoryConstrained];
SetAttributes[totalMemoryConstrained,HoldRest];
模块[{memException},
totalMemoryConstrained[最大值,正文,故障表达式]:=
抓住[记忆训练过的]身体,
评估[
如果[#<0,则抛出[failexpr,memException],#]&@(最大值)-
MemoryUse[])],failexpr],memException]];
将尝试约束内核使用的总内存,而不仅仅是在给定的特定计算中。因此,您可以尝试将其包装在顶级函数调用中,只需一次。因为它依赖于
MemoryConstrained
和MemoryInUse
,所以它只和它们一样好。有关如何使用它的更多详细信息,请参阅Mathgroup post。您可以使用$Pre
自动将其应用到您的输入中,并减少样板代码的数量。问题的第二部分对于Mathematica用户来说非常实际。我已经在官方新闻组中提出了相关问题,得到了以下信息:
2011年3月10日星期四06:12:04-0500
(美国东部时间)亚历克赛·波普科夫写道:
我更喜欢的不是记忆训练
“FreeMemoryConstrained”
用于防止安全交换的功能
这不是现代的运作方式
系统工作。所有内存都是虚拟的
记忆。无论它是否有RAM支持,
磁盘或某些其他存储介质已损坏
操作系统的详细信息
管理而不是应用程序(使用
机制例外,如
内存映射文件)。如果
应用程序确实有能力
将其内存锁定在RAM中,这将是
对别人确实很不友好
系统上的应用程序
你真的想要一个这样的应用程序吗
坚持保留2G内存
自作主张
可容纳200个用户的应用程序
梅格
ClearAll[totalMemoryConstrained];
SetAttributes[totalMemoryConstrained, HoldRest];
Module[{memException},
totalMemoryConstrained[max_, body_, failexpr_] :=
Catch[MemoryConstrained[body,
Evaluate[
If[# < 0, Throw[failexpr, memException], #] &@(max -
MemoryInUse[])], failexpr], memException]];