有時,當我在Mathematica中編寫實驗代碼時,我很擔心我是否應該評估它,因爲它可能最終導致我的系統屈服於膝蓋。Mathematica中的異步評估
作爲一個人爲的例子,如果您嘗試在64位機器上運行以下代碼片段,它很可能會導致您的系統在耗盡所有內存後磨碎到完全停止。
junk = Table[{x, x}, {10^9}]; (* nom nom nom memory. Please don't run this. *)
當然,你可以只是把MemoryConstrained
到它,並希望最好的,但有時你不希望它阻止任何進一步的輸入。爲此,我認爲最好能夠實現中間立場的方式是在單獨的內核中進行評估。
這是體面很容易的做到:
ClearAll[GetAvailableKernel];
GetAvailableKernel[] := Block[{i, kernels},
kernels = Kernels[];
If[[email protected] != 0,
For[i = 1, i <= [email protected], i++,
If[kernels[[i, 1, 2]] > 0, [email protected][[i]]]
]
];
LaunchKernels[1]]
ClearAll[SafeEvaluate];
SetAttributes[SafeEvaluate, HoldFirst];
Options[SafeEvaluate] = {"EvaluationKernel" -> Null,
"ConstrainMemory" -> True, "MaxMemory" -> 2 1024^3};
SafeEvaluate[expr_, OptionsPattern[]] := Block[{evalkernel, result},
If[OptionValue["EvaluationKernel"] != Null,
evalkernel = OptionValue["EvaluationKernel"],
evalkernel = GetAvailableKernel[]
];
result = If[OptionValue["ConstrainMemory"],
With[{memory = OptionValue["MaxMemory"]},
ParallelEvaluate[MemoryConstrained[expr, memory], evalkernel]],
ParallelEvaluate[expr, evalkernel]];
result]
然後,你可以先走一步,做線沿線的東西:
SafeEvaluate[Table[{x, x}, {1024^3}]]
而且數學會優雅地恢復$Aborted
告訴你,它跑了內存不足。通過在單獨的內核中進行評估,我們可以將代碼存儲到它自己的並行內核中。如果出現問題,那麼我們的主內核不受影響。
這引出了我的主要觀點:我怎樣才能在Mathematica實現異步的評價?
我現在的工作,但它完全阻止任何進一步的用戶輸入。我不能只是設置,忘記和稍後檢查。
有什麼想法?
您精心描述`SafeEvaluate`但你花幾句您的實際問題和我剩下的猜測它的意思。您是否正在尋找一種方法來評估一個單元格中的表達式,使評估運行並評估第二個單元格中的表達式,在第一個單元格的評估完成之前可能會得出結果? – 2011-12-15 08:55:21
@ Mr.Wizard這是我對這個問題的解讀。我的第一個想法是,這是不可能的,因爲任何評估都會改變內核狀態。因此,兩個並行的評估將模擬地改變內核狀態:邁克實際上要求多線程,它帶來了所有的困難和微妙之處。 (即使使用並行內核,一些狀態也會被共享以獲得結果。)但是後來我想到了Dynamic [f [i]]`,Table [Pause [1];我,{我,10}]`(嘗試它 - 就像'監視器')。這實際上是在單個內核中並行地評估事物。 – Szabolcs 2011-12-15 09:13:02
@Szabolcs他說他想在單個內核中進行並行評估? – 2011-12-15 09:18:40