Как распараллелить код julia без изменения конечного результата? - PullRequest
0 голосов
/ 26 октября 2018

Я новичок в параллельных вычислениях и сумел изменить свой код таким образом, чтобы он работал быстрее, чем мой непараллельный код, однако мои результаты немного отличаются.Я пытался использовать макросы @sync, @async, @threads и @distributed, но ни один из них, похоже, не дает правильного результата.

Цель состоит в том, чтобы найти кратчайший путь через лабиринт, и хотя непараллельный запуск кода работает нормально, кажется, что параллельный запуск кода не завершает все итерации алгоритма поиска и, в свою очередь, дает только кратчайший путь.через лабиринт, найденный одним из потоков / рабочих.

Он в основном работает, начиная с входа, перебирая все возможные точки, к которым он может перейти к выходу, затем выбирает точку, к которой он достиг самого быстрогои повторяет эти шаги, пока не будет достигнут выход.Он делает это, используя два не вложенных цикла for, но когда я увеличиваю скорость выполнения с помощью макросов, таких как @async или @distributed, он никогда не находит кратчайший путь.

Есть ли способ сделать это одновременно или параллельно, в то же время получая тот же результат в конце?

Редактировать:

Я добавил примерфункции, которая имеет ту же проблему.Как вы сможете получить такое же значение z в конце, ускоряя процесс параллелизации?

    a = rand(1, 2, 15)
    function stufftodo(a)                           
        z = 0
        y = rand(size(a)[1], size(a)[2]) .* 1000
        for i in 1:size(a)[3]
            x = a[:, :, i]
            sleep(0.05)
            if sum(y)>sum(x)
                y=x
            end
        end
        z = minimum(y)
    end

1 Ответ

0 голосов
/ 27 октября 2018

Здесь, любые вопросы приветствуются:

Давайте определим данные для воспроизводимости этого примера:

using Random
Random.seed!(0)
a = rand(1, 2, 15)

Мы начнем с измерения времени исходной функции.Так как Джулия в первый раз запускает @time, она компилирует код, который мы измеряем дважды (допустимо только второе измерение):

julia> @time stufftodo(a)
  1.017913 seconds (654.90 k allocations: 33.067 MiB, 0.81% gc time)
0.042301665932029664

julia> @time stufftodo(a)
  0.772471 seconds (538 allocations: 69.813 KiB)
0.042301665932029664

Теперь давайте распределимся:

using Distributed
nworkers()<4 && addprocs(4)

@everywhere function stufftodo2(a)
    y = rand(size(a)[1], size(a)[2]) .* 1000
    aggfunc = (x,y) -> sum(y)>sum(x) ? x : y
    y = @distributed (aggfunc) for i in 1:size(a)[3]
        sleep(0.05)
        a[:, :, i]
    end
    minimum(y)
end

Теперьмы можем измерить время распределенной функции (опять-таки только второе измерение действительно):

julia> @time stufftodo2(a)
  2.819767 seconds (2.46 M allocations: 124.442 MiB, 1.53% gc time)
0.042301665932029664

julia> @time stufftodo2(a)
  0.206596 seconds (447 allocations: 44.609 KiB)
0.042301665932029664
...