首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Mathematica中监控并行计算的进度

在Mathematica中监控并行计算的进度
EN

Stack Overflow用户
提问于 2011-09-09 01:58:52
回答 3查看 6.4K关注 0票数 20

我正在构建一个大型的ParallelTable,并希望对计算过程保持一定的了解。对于非平行表,下面的代码做得很好:

代码语言:javascript
运行
复制
counter = 1;
Timing[
 Monitor[
  Table[
   counter++
  , {n, 10^6}];
 , ProgressIndicator[counter, {0, 10^6}]
 ]
]

结果为{0.943512, Null}。然而,对于并行的情况,有必要在内核之间共享counter

代码语言:javascript
运行
复制
counter = 1;
SetSharedVariable[counter];
Timing[
 Monitor[
  ParallelTable[
   counter++
  , {n, 10^4}];
 , ProgressIndicator[counter, {0, 10^4}]
 ]
]

结果为{6.33388, Null}。由于counter的值在每次更新时都需要在内核之间来回传递,因此对性能的影响非常严重。对于如何了解计算的进展,有什么想法吗?也许让每个内核都有自己的counter值,然后每隔一段时间对它们求和?也许可以用某种方法来确定表中的哪些元素已经扩展到内核中了?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-09-11 12:40:43

当您说“也许让每个内核都有自己的counter值并按时间间隔对它们求和?”时,您几乎给出了答案。

尝试如下所示:

代码语言:javascript
运行
复制
counter = 1;
SetSharedVariable[counter];
ParallelEvaluate[last = AbsoluteTime[]; localcounter = 1;]
Timing[Monitor[
  ParallelTable[localcounter++; 
    If[AbsoluteTime[] - last > 1, last = AbsoluteTime[]; 
     counter += localcounter; localcounter = 0;], {n, 10^6}];, 
  ProgressIndicator[counter, {0, 10^6}]]]

请注意,它比第一个单CPU用例花费的时间更长,因为它实际上在循环中做了一些事情。

您可以将测试AbsoluteTime[] - last >1更改为更频繁的值,如AbsoluteTime[] - last > 0.1。

票数 15
EN

Stack Overflow用户

发布于 2011-11-12 06:51:50

另一种方法是对LinkWrite和LinkRead进行跟踪,并修改它们的跟踪消息以进行一些有用的统计。

首先,启动一些并行内核:

代码语言:javascript
运行
复制
LaunchKernels[]

这将为并行内核设置链接对象。

然后为链接读写计数器定义一个init函数:

代码语言:javascript
运行
复制
init[] := Map[(LinkWriteCounter[#] = 0; LinkReadCounter[#] = 0) &, Links[]]

接下来,当这些计数器的链接被读取或写入时,您希望递增这些计数器:

代码语言:javascript
运行
复制
Unprotect[Message];
Message[LinkWrite::trace, x_, y_] := LinkWriteCounter[x[[1, 1]]] += 1;
Message[LinkRead::trace, x_, y_] := LinkReadCounter[x[[1, 1]]] += 1;
Protect[Message];

这里,x[[1,1]]是有问题的LinkObject。

现在,在LinkWrite和LinkRead上启用跟踪:

代码语言:javascript
运行
复制
On[LinkWrite];
On[LinkRead];

要格式化进度显示,首先将LinkObject显示缩短一点,因为它们相当冗长:

代码语言:javascript
运行
复制
Format[LinkObject[k_, a_, b_]] := Kernel[a, b]

这是一种动态显示子内核链接的读取和写入的方法:

代码语言:javascript
运行
复制
init[];
Dynamic[Grid[Join[
  {{"Kernel", "Writes", "Reads"}}, 
  Map[{#, LinkWriteCounter[#]/2, LinkReadCounter[#]/2} &, 
  Select[Links[], StringMatchQ[First[#], "*subkernel*"] &
]]], Frame -> All]]

(我将计数除以2,因为每个链接的读取和写入都会被跟踪两次)。

最后用一个10,000个元素的表进行测试:

代码语言:javascript
运行
复制
init[];
ParallelTable[i, {i, 10^4}, Method -> "FinestGrained"];

如果一切正常,您应该会看到最终的进度显示,每个内核大约有5,000次读写操作:

这有中等的性能损失:不使用监视器时为10.73秒,使用监视器时为13.69秒。当然,对于这种特殊的并行计算,使用"FinestGrained“选项并不是最好的方法。

票数 4
EN

Stack Overflow用户

发布于 2011-09-09 12:34:52

你可以从Yuri Kandrashkin开发的Spin`System`LoopControl`包中得到一些想法:

Announce of the Spin` package:

代码语言:javascript
运行
复制
Hi group,

I have prepared the package Spin` that consists of several applications
which are designed for research in the area of magnetic resonance and 
spin chemistry and physics.

The applications Unit` and LoopControl` can be useful to a broader
audience.

The package and short outline is available at:
http://sites.google.com/site/spinalgebra/.

Sincerely,
Yuri Kandrashkin. 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7352461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档