gpt4 book ai didi

parallel-processing - 你如何打破并行循环?平行休息

转载 作者:行者123 更新时间:2023-12-04 08:03:15 25 4
gpt4 key购买 nike

在下面的代码片段中,如果您将 Do 替换为 ParallelDo,它的计算速度将降低 3 倍,因为现在循环将仅在两个内核之一中中断。

ParallelEvaluate[NN = 10070];
SetSharedVariable[res]
Module[{a, b, c},
Do[
c = NN - a - b;
If[a a + b b == c c, res = a b c; Break[]]
, {a, 1, NN}, {b, a + 1, NN}
];
res
] // AbsoluteTiming

调用 ParallelAbort 可以解决问题,但这是被禁止的。还有什么?

最佳答案

你需要有一种方法来告诉每次迭代已找到答案的所有其他迭代。我用一个“退出”标志建模,最初设置为假,即在任何迭代时设置为真决定完成。每个迭代同样有检查退出条件。

我的 Mathematica 已经 15 年生锈了,我还没有之前看过 Parallelxxx 表格,但猜得不错循环应该如何改变如下您的代码的变体:

ParallelEvaluate[NN = 10070];
SetSharedVariable[res,quit]
Module[{a, b, c},
quit=false;
Do[ c = NN - a - b;
If[quit, Break[]];
If[ a a + b b == c c, quit=true; res = a b c; Break[]],
{a, 1, NN}, {b, a + 1, NN}
];
res
] // AbsoluteTiming

额外的 If 稍微减慢了循环,但这就是代价同步。

我怀疑金额您在每次迭代中所做的工作已经非常少与并行执行每次迭代的成本相比,所以这个循环可能效率低下,你可能得不到Do Parallel 的任何实际值(value)。如果你不这样做,那么你可以让每个 Do 迭代都对多个值进行操作a 和 b 的(例如,使用 {a, 1, NN, 10} 并且类似地对每个 b迭代并将 10 宽子范围作为内部子循环处理每次并行迭代)。以保持退出测试退出开销比较小在每个循环体中完成的工作。留给读者重新编码练习。

您的代码还有另一个问题:设置中存在竞争条件水库在某些情况下,两次迭代都可以决定设置 res。如果您不关心产生哪个答案,并且 res 的存储是“原子的”,这可以。如果 res 是一个更复杂的数据结构,并且更新它需要多个 Mathematica 语句,你肯定会有一场数据竞赛你的循环偶尔会产生不好的结果将很难调试。理想情况下,您需要某种原子测试以保护退出条件。我不知道MMa里面是什么,所以你必须查一下,但我想象一个“原子[...]”形式坚持其主体仅由许多并行线程中的一个执行。(也许 MMa 有一个信号量,您可以使用它来实现原子性]。如果是这样,您的代码应如下所示:

ParallelEvaluate[NN = 10070];
SetSharedVariable[res,quit]
Module[{a, b, c},
quit=false;
Do[ c = NN - a - b;
If[quit, Break[]];
If[ a a + b b == c c,
atomic[If[not[quit]; quit=true; res = a b c;]; Break[]],
{a, 1, NN}, {b, a + 1, NN}
];
res
] // AbsoluteTiming

关于parallel-processing - 你如何打破并行循环?平行休息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1294294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com