我是朱莉娅的新手,最近正在研究朱莉娅并行计算。
在阅读相关文档后,我仍然不清楚朱莉娅的并行性的准确机制,包括宏\@sync
和\@async
。
以下是Julia v0.5 documentation中的pmap
函数:
function pmap(f, lst)
np = nprocs() # determine the number of processes available
n = length(lst)
results = Vector{Any}(n)
i = 1
# function to produce the next work item from the queue.
# in this case it's just an index.
nextidx() = (idx=i; i+=1; idx)
@sync begin
for p=1:np
if p != myid() || np == 1
@async begin
while true
idx = nextidx()
if idx > n
break
end
results[idx] = remotecall_fetch(f, p, lst[idx])
end
end
end
end
end
results
end
不同的两个处理器/工作人员是否可以同时呼叫nextidx()
获得相同的idx = j
?如果是,我觉得results[j]
将被计算两次,result[j+1]
将无法计算。
非常感谢。
更多调查结果:
function f1()
i=1
nextidx()=(idx=i;sleep(1);i+=1;idx)
for p=1:2
@async begin
idx=nextidx()
println(idx)
end
end
end
f1()
结果是1 1
。
通过这个,我发现两个任务调用函数nextidx()
的时间段可能会重叠。所以我觉得在第一个代码中,
如果np = 3
(即两个工人),n
的长度lst
非常大,比如10 ^ 8,
任务可以获得相同的索引。
它可能只是因为时间上的巧合而发生,即两个任务在几乎相同的时间点采用表达式idx = i
,因此代码不稳定。
我是对的吗?
答案 0 :(得分:0)
不,只要您正确安排工作。 pmap
documentation指出主进程按顺序调度作业;只有并行执行是异步的。编码的pmap
不需要线程锁定以确保正确的作业调度。将sleep
添加到nextidx
会故意破坏此功能并引入您观察到的竞争条件。假设所有进程共享状态 - 这是nextidx
函数的目的 - 那么主进程将不会安排两次相同的作业。