Прежде всего, doSNOW
и doParallel
- это два разных пакета, которые предоставляют бэкэнды для foreach
.
Вы можете, конечно, проверить оба,
только не запутайся.
Следующие работы для любого,
но ваш вопрос более тесно связан с использованием пакета parallel
(который входит в R).
Ваш подход не будет работать, потому что даже если вы поместите свою среду в каждого параллельного работника,
это будут копии, которые будут изменены независимо:
foreach(i = 1L:2L) %dopar% {
.someEnv$hello <- "world"
.someEnv$hello
}
[[1]]
[1] "world"
[[2]]
[1] "world"
print(.someEnv$hello)
NULL
Однако вы можете использовать пакет bigmemory
:
library(doParallel)
library(bigmemory)
cl <- makeCluster(4L)
registerDoParallel(cl)
var <- 1L:10L
squared <- big.matrix(nrow = 10L, ncol = 1L, type = "integer")
# show by coercing to normal matrix
squared[,]
[1] NA NA NA NA NA NA NA NA NA NA
squared_desc <- describe(squared)
# assign it to each worker's global environment
clusterExport(cl, c("squared_desc"))
foreach(i = 1L:10L,
.noexport = c("squared_desc"),
.packages = "bigmemory") %dopar%
{
squared <- attach.big.matrix(squared_desc)
squared[i] <- var[i] * var[i]
NULL
}
stopCluster(cl); registerDoSEQ()
squared[,]
[1] 1 4 9 16 25 36 49 64 81 100
Обратите внимание, что матрицы из bigmemory
строго типизированы внутри,
так что если вы определите их как целые числа,
Вы должны присвоить им значения, которые являются целыми числами,
которые явно указаны в R добавлением L
в конце числа,
в противном случае вы получите предупреждение об унынии.
Кроме того, вам не нужно принуждать все big.matrix
, чтобы использовать его,
но почти каждый раз, когда вы получаете доступ к его элементам, вы копируете некоторые данные в обычную матрицу / вектор R.
РЕДАКТИРОВАТЬ: и, наконец, я думаю, что bigmemory
не предоставляет никаких механизмов синхронизации для защиты от условий гонки.