在所有处理器上运行循环并在Julia中增加一个变量

时间:2018-08-16 08:57:46

标签: parallel-processing julia

我有一个函数const cons = (x, y) => f => f(x, y); const pair = cons(5, 3); //const car = pair => pair((x, y) => x); const cdr = pair => pair((x,y) => y); function car(pair){ var result= pair( function temp(x, y){ return x; } ); return result; } const carCall = car(pair); const cdrCall = cdr(pair); console.log(carCall); console.log(cdrCall);,它需要很长时间才能计算出来。我需要运行仿真,然后检查某些条件以增加单个变量。

sim

如何在多个处理器上运行它?在这种情况下,我不太了解如何使用switches = 0 @showprogress 1 "Computing ..." for i = 1:100 m0 = data[i] m = sim(data[i]) if allSwitch(m0, m) switches += 1 end end pmap,尤其是因为我需要增加@parallel且我不知道作业是否可以访问该变量。

1 个答案:

答案 0 :(得分:1)

在并行运行中,通常不希望您的进程写入相同的位置。例如,当switches的当前值为0并且两个进程希望同时递增switches时,它们都将开关读为0,并将其递增为1,而您想要{{ 1}}在这种情况下为2。这在并行计算中称为 coherence 问题。您可能想对这些变量使用 atomic访问-修改操作,但这会在使用原子操作的区域中序列化程序,从而降低并行性能。

对于您而言,有几种方法可以解决一致性问题。一种这样的方式是,您的每个进程都可以存储自己的switches,然后在并行执行结束时将所有switches求和,得到最终结果,称为 reduce操作。为此,您可以在Julia中创建一个switches,然后每个进程都写入自己的索引(每个进程都有一个SharedArray给出的唯一ID)。或者,您可以简单地使用myid()(0.6中的@distributed)宏来轻松实现这一目标。

@parallel

我们将归约运算指定为与using Distributed addprocs(4) # adds 4 processes switches = @distributed (+) for i = 1:100 m0 = data[i] m = sim(data[i]) allSwitch(m0, m) # this is the value to be added to `switches` since it is already binary it will increment switches if `allSwitch` returns true end 相加。如果您的julia版本为0.6,则应删除(+)并将using Distributed替换为@distributed

在Julia 1.0中,使用@parallel,您的循环可以读取外部变量,但对于写入访问,则应创建一个@distributed。但是,在您的情况下则不需要。

这里是另一个示例,它对数组中的偶数求和:

SharedArray

另一种方法是使用function sumeven(data) evensum = @distributed (+) for i = 1:length(data) if data[i] % 2 == 0 data[i] # if even add data[i] to the sum else 0 # if not add 0 end # you can instead write `ifelse(data[i] % 2 == 0, data[i], 0)` end evensum end # try evensum d = rand(1:100, 10000) # creates a random integer array of size 10000 selected from 1 to 100. parallel_result = evensum(d) 。您可以编写一个函数来处理给定pmap实例的for循环内的内容。然后将此功能与data和您的pmap一起使用,将为您提供data,该BitArray的索引allSwitch被评估为真。比起您可以使用count函数来计算返回true的次数而言。重要的是要注意,pmap默认情况下将任务一一分发给进程(受batch_size参数控制),而@distributed则将任务分成大块。如果每个任务花费的时间很大且不均匀,则应考虑使用pmap而不是@distributed

您应该查看Julia中的并行计算文档。

https://docs.julialang.org/en/stable/manual/parallel-computing/#