Подтвердить что ты не робот

Понимание различий между mclapply и parLapply в R

Недавно я начал использовать параллельные методы в R для проекта, и моя программа работает в системах Linux, используя mclapply из parallel. Тем не менее, я попал в дорожный блок с моим пониманием parLapply для Windows.

Используя mclapply, я могу установить количество ядер, итераций и передать их существующей функции в моем рабочем пространстве.

mclapply(1:8, function(z) adder(z, 100), mc.cores=4)

Кажется, я не могу добиться того же в Windows, используя parLapply. Насколько я понимаю, мне нужно передать все переменные с помощью clusterExport() и передать фактическую функцию, которую я хочу применить в аргументе.

Правильно ли это или что-то похожее на функцию mclapply, которая применима к Windows?

4b9b3361

Ответ 1

Красота mclapply в том, что рабочие процессы все созданы как клоны мастера прямо в точке, что mclapply называется, так что вам не придется беспокоиться о воспроизведении среды на каждом кластере работников. К сожалению, это невозможно в Windows.

При использовании parLapply вам обычно необходимо выполнить следующие дополнительные шаги:

  • Создание кластера PSOCK
  • При необходимости зарегистрируйте кластер
  • Загрузите необходимые пакеты для сотрудников кластера.
  • Экспорт необходимых данных и функций в глобальную среду рабочих групп.

Кроме того, когда все будет готово, рекомендуется отключить кластер PSOCK с помощью stopCluster.

Здесь перевод вашего примера на parLapply:

library(parallel)
cl <- makePSOCKcluster(4)
setDefaultCluster(cl)
adder <- function(a, b) a + b
clusterExport(NULL, c('adder'))
parLapply(NULL, 1:8, function(z) adder(z, 100))

Если вашей функции adder требуется пакет, вам придется загрузить этот пакет для каждого из рабочих, прежде чем называть его parLapply. Вы можете сделать это довольно легко с помощью clusterEvalQ:

clusterEvalQ(NULL, library(MASS))

Обратите внимание, что NULL Первый аргумент clusterExport, clusterEval и parLapply указывает на то, что они должны использовать объект кластера, зарегистрированный с помощью setDefaultCluster. Это может быть очень полезно, если ваша программа использует mclapply во многих различных функциях, так что вы не должны передавать объект кластера для каждой функции, которая нуждается в ней при преобразовании программы использовать parLapply.

Конечно, adder может вызывать другие функции в вашей глобальной среде, которые вызывают другие функции и т.д. В этом случае вам также придется экспортировать их и загрузить любые необходимые им пакеты. Также обратите внимание, что если любые переменные, которые вы экспортировали, меняются в ходе вашей программы, вам придется экспортировать их снова, чтобы обновить их у сотрудников кластера. Опять же, это необязательно с mclapply, потому что он всегда создает/клонирует/разворачивает рабочих каждый раз, когда он вызывается, делая это ненужным.

Ответ 2

mclapply проще в использовании и использует базовую функциональность операционной системы fork() для достижения параллелизации. Однако, поскольку Windows не имеет fork(), вместо этого будет выполняться стандартное lapply - нет распараллеливания.

parLapply - это другой зверь. Он создаст кластер процессов, которые могут даже размещаться на разных компьютерах в вашей сети, и они обмениваются данными через TCP/IP, чтобы передавать задачи и результаты между собой.

Проблема в вашем коде заключается в том, что вы не понимали, что первый параметр для parLapply должен быть "кластерным" объектом. Самый простой пример использования parLapply для запуска на одной машине, о которой я могу думать, таков:

library(parallel)

# Spawn child processes using fork() on the local machine
cl <- makeForkCluster(getOption("cl.cores", 2))

# Use parLapply to calculate lengths of 1000 strings
text = rep("Hello, world!", 1000)
len = parLapply(cl, text, nchar)

# Kill child processes since they are no longer needed
stopCluster(cl)

Использование parLapply с кластером, созданным с использованием makeForkCluster, как указано выше, функционально эквивалентно вызову mclapply. Таким образом, он также не будет работать в Windows.:) Посмотрите на другие способы создания кластера с makeCluster и makePSOCKcluster в документации и посмотрите, что лучше всего подходит для ваших требований.