Разъяснение преимуществ использования и процесса использования потоков - PullRequest
2 голосов
/ 09 июля 2020

Я новичок в использовании Julia, и после нескольких курсов по numeri c анализ программирования стал моим хобби. Я провел несколько тестов со всеми своими ядрами и сделал то же самое с потоками для сравнения. Я заметил, что выполнение более тяжелых вычислений с потоковым l oop прошло лучше, чем с процессом, но примерно так же было, когда дело дошло до сложения. (операции были выбраны случайным образом, например). После некоторого исследования все довольно расплывчато, и в конечном итоге я хочу получить некоторую точку зрения от кого-то, кто использует тот же язык, если это вообще имеет значение.

Некоторая техническая информация: 8 физических ядер, Джулия добавлен вектор из 16 после addprocs() и nthreads() is 16

using Distributed
addprocs()
@everywhere using SharedArrays;
@everywhere using BenchmarkTools;

function test(lim)
    r = zeros(Int64(lim / 16),Threads.nthreads())
    Threads.@threads for i in eachindex(r)
        r[Threads.threadid()] = (BigInt(i)^7 +5)%7; 
    end
    return sum(r)
end
@btime test(10^4)   # 1.178 ms (240079 allocations: 3.98 MiB)

@everywhere function test2(lim)
    a = SharedArray{Int64}(lim);
    @sync @distributed for i=1:lim
        a[i] = (BigInt(i)^7 +5)%7;
    end
    return sum(a)
end
@btime test2(10^4)  # 3.796 ms (4413 allocations: 189.02 KiB)

1 Ответ

2 голосов
/ 09 июля 2020

Обратите внимание, что ваши циклы делают разные вещи.

  1. Int первый l oop каждый поток продолжает обновлять одну и ту же единственную ячейку массива. Скорее всего, поскольку в одном потоке обновляется только одна ячейка памяти, механизм кэширования процессора можно использовать для ускорения работы. С другой стороны, второй l oop каждый процесс обновляет несколько разных ячеек памяти, и такое кеширование невозможно.
  2. Первый Array содержит Float64 значений, а второй - Int64 значений

После исправления этих вещей разница становится меньше (это на моем ноутбуке, у меня всего 8 потоков):

julia> @btime test(10^4)
  2.781 ms (220037 allocations: 3.59 MiB)
29997

julia> @btime test2(10^4)
  4.867 ms (2145 allocations: 90.14 KiB)
29997

Теперь другая проблема заключается в том, что когда Distributed used вы выполняете межпроцессное взаимодействие, чего не происходит при использовании Threads. По сути, межпроцессную обработку не имеет смысла использовать для заданий продолжительностью несколько миллисекунд. Когда вы пытаетесь увеличить объемы обработки, разница может составить dimini sh.

Итак, когда использовать что - зависит от .. Общие рекомендации (несколько субъективные) следующие:

  1. Процессы более устойчивы (потоки все еще экспериментальны)
  2. Потоки проще, если вам не нужно использовать блокировку или атоми c значения
  3. Когда уровень параллелизма превышает 16 потоки становятся неэффективными, и следует использовать Distributed (это мое личное наблюдение)
  4. При написании служебных пакетов для других используйте потоки - не распространяйте код внутри пакета. Объяснение: Если вы добавляете многопоточность в пакет, его поведение может быть прозрачным для пользователя. С другой стороны, абстракция многопроцессорной обработки (Distributed пакет) Джулии не делает различий guish между параллельным и распределенным - то есть ваши рабочие могут быть локальными или удаленными. Это принципиально отличается от того, как разработан код (например, SharedArrays против DistributedArrays), более того, дизайн кода также может зависеть, например, от количества серверов или возможностей ограничения межузловой связи. Следовательно, обычно Distributed-связанный пакет logi c должен быть отделен от стандартного пакета служебных программ, в то время как многопоточная функциональность может быть просто сделана прозрачной для пользователя пакета. Конечно, есть некоторые исключения из этого правила, такие как предоставление некоторых серверных инструментов распределенной обработки данных и т. Д. c. но это общее эмпирическое правило.
  5. Для крупномасштабных вычислений я всегда использую процессы, потому что вы можете легко go поместить их в компьютерный кластер и распределить рабочую нагрузку между сотнями машин.
...