Câu hỏi có vẻ giống như một mẫu cơ bản để thực hiện các tác vụ tìm kiếm "lúng túng song song". Cấu trúc @parallel for
rất tốt cho việc phân vùng, nhưng không có logic ngắn mạch break
để dừng dưới dạng for
trong quy trình xử lý đơn lẻ.
Để chứng minh làm thế nào để làm điều này trong Julia xem xét một vấn đề đồ chơi của việc tìm kiếm sự kết hợp của một khóa kết hợp với một số bánh xe. Mỗi thiết lập của một bánh xe có thể được kiểm tra tính chính xác với một số phương pháp (lấy một thời gian combodelay
- xem mã dưới đây). Sau khi tìm thấy số chính xác cho bánh xe, bánh xe tiếp theo sẽ được tìm kiếm. Mã pseudo cấp cao giống như đoạn mã được đưa ra trong câu hỏi OP.
Sau đây là mã đang chạy (trên 0,5 và 0,6) để thực hiện việc này. Một số ý kiến giải thích chi tiết, và mã được đưa ra trong một đoạn duy nhất để dễ dàng cắt và dán.
# combination lock problem parameters
const wheel_max = 1000 # size of wheel
@everywhere const magic_number = [55,10,993] # secret combination
const wheel_count = length(magic_number) # number of wheels
const combodelay = 0.01 # delay time to check single combination
# parallel short-circuit parameters
const check_to_work_ratio = 160 # ratio to limit short-circuit overhead
function find_combo(wheel,combo=Int[])
done = SharedArray{Int}(1) # shared variable to hold if and what combo
done[1] = 0 # succeded. 0 means not found yet
# setup counters to limit parallel overhead
@sync begin
@everywhere global localdone = false
@everywhere global checktime = 0.0
@everywhere global worktime = 0.0
end
# do the parallel work
@sync @parallel for i in 1:wheel_max
global localdone
global checktime
global worktime
# if not checking too much, look at shared variable
if !localdone && check_to_work_ratio*checktime < worktime
tic()
localdone = done[1]>0
checktime += toq()
end
# if no process found combo, check another combo
if !localdone
tic()
sleep(combodelay) # simulated work delay, {..statement..} from OP
if i==magic_number[wheel] # {condition} from OP
done[1] = i
localdone = true
end
worktime += toq()
else
break
end
end
if done[1]>0 # check if shared variable indicates combo for wheel found
push!(combo,done[1])
return wheel<wheel_count ? find_combo(wheel+1,combo) : (combo,true)
else
return (combo,false)
end
end
function find_combo_noparallel(wheel,combo=Int[])
found = false
i = 0
for i in 1:wheel_max
sleep(combodelay)
if i==magic_number[wheel]
found = true
break
end
end
if found
push!(combo,i)
return wheel<wheel_count ?
find_combo_noparallel(wheel+1,combo) : (combo,true)
else
return (combo,false)
end
end
function find_combo_nostop(wheel,combo=Int[])
done = SharedArray{Int}(1)
done[1] = 0
@sync @parallel for i in 1:wheel_max
sleep(combodelay)
if i==magic_number[wheel]
done[1] = i
end
end
if done[1]>0
push!(combo,done[1])
return wheel<wheel_count ?
find_combo_nostop(wheel+1,combo) : (combo,true)
else
return (combo,false)
end
end
result = find_combo(1)
println("parallel with short-circuit stopping: $result")
@assert result == (magic_number, true)
result = find_combo_noparallel(1)
println("single process with short-circuit stopping: $result")
@assert result == (magic_number, true)
result = find_combo_nostop(1)
println("parallel without short-circuit stopping: $result")
@assert result == (magic_number, true)
println("\ntimings")
print("parallel with short-circuit stopping ")
@time find_combo(1);
print("single process with short-circuit stopping ")
@time find_combo_noparallel(1)
print("parallel without short-circuit stopping ")
@time find_combo_nostop(1)
nothing
Có thể triển khai tìm kiếm tốt hơn và một số chương trình meta có thể ẩn một số máy móc ngắn mạch. Nhưng điều này sẽ tốt như một sự khởi đầu.
Kết quả sẽ giống xấp xỉ như thế này:
parallel with short-circuit stopping: ([55,10,993],true)
single process with short-circuit stopping: ([55,10,993],true)
parallel without short-circuit stopping: ([55,10,993],true)
timings
parallel with short-circuit stopping 4.473687 seconds
single process with short-circuit stopping 11.963329 seconds
parallel without short-circuit stopping 11.316780 seconds
này được tính cho cuộc biểu tình với 3 quá trình lao động. Vấn đề thực sự cần có nhiều quy trình hơn và nhiều công việc hơn cho mỗi quá trình và sau đó lợi ích của việc đoản mạch sẽ hiển nhiên.