запись в глобальные переменные при использовании doSNOW и параллелизации в R? - PullRequest
6 голосов
/ 23 февраля 2012

Есть ли проблема при доступе / записи в глобальную переменную при использовании пакета doSNOW на нескольких ядрах?

В приведенной ниже программе каждый из MyCalculations (ii) записывает в ii-й столбец матрицы"globalVariable" ...

Как вы думаете, результат будет правильным?Будут ли скрытые уловы?

Большое спасибо!

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

library(doSNOW)
MaxSearchSpace=44*5
globalVariable=matrix(0, 10000, MaxSearchSpace)
cl<-makeCluster(7)
registerDoSNOW(cl)
foreach (ii = 2:nMaxSearchSpace, .combine=cbind, .verbose=F) %dopar%
  {
   MyCalculations(ii)
  }

stopCluster(cl)

ps Я спрашиваю - в рамках DoSnow существует ли какая-либо опасность доступа/ запись глобальных переменных ... thx

1 Ответ

7 голосов
/ 13 мая 2012

Поскольку этому вопросу пару месяцев, надеюсь, вы уже нашли ответ. Однако, если вы все еще заинтересованы в обратной связи, вот что нужно учитывать:

При использовании foreach с параллельным бэкэндом вы не сможете назначать переменные в глобальной среде R так, как вы пытаетесь (вы, вероятно, заметили это). При использовании последовательного бэкенда назначение будет работать, но без использования параллельного , как при doSNOW.

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

Мое предложение начинается аналогично вашему примеру:

library(doSNOW)
MaxSearchSpace <- 44*5
cl <- makeCluster(parallel::detectCores())

# do not create the globalVariable object

registerDoSNOW(cl)

# Save the results of the `foreach` iterations as 
# lists of lists in an object (`theRes`)

theRes <- foreach (ii = 2:MaxSearchSpace, .verbose=F) %dopar%
  {
# do some calculations
   theNorms <- rnorm(10000)
   thePois <- rpois(10000, 2)
# store the results in a list
   list(theNorms, thePois)
  }

После завершения всех итераций извлеките результаты из theRes и сохраните их как объекты (например, globalVariable, globalVariable2 и т. Д.)

globalVariable1 <- do.call(cbind, lapply(theRes, "[[", 1))
globalVariable2 <- do.call(cbind, lapply(theRes, "[[", 2))

С учетом этого, если вы выполняете вычисления для каждой итерации, которые зависят от результатов вычислений из предыдущих итераций, то этот тип параллельных вычислений не является подходом для использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...