Если вы можете массировать ваши данные в основном процессе R, вы можете попробовать преобразовать каждый 2-мерный срез в big.matrix
из пакета bigmemory
и использовать его в своих параллельных рабочих.Это было бы полезно, только если время, необходимое для обработки каждого слайса в подчиненном процессе, является значительным.
См. Этот пример и обратите внимание, что вы можете вкладывать 2 foreach
циклов с %:%
m <- as.numeric(1:16)
dim(m) <- rep(2L, 4L)
# use %do% for sequential processing, without copying the data to parallel workers
big_m <- foreach(i=1L:2L, .combine=c) %:% foreach(j=1L:2L, .combine=list) %do% {
as.big.matrix(m[,,i,j], type="double")
}
descriptors <- lapply(big_m, describe)
# specify .noexport to avoid copying the data to each worker
foreach(m_slice_desc=descriptors, .packages=c("bigmemory"), .noexport=ls(all.names=TRUE)) %dopar% {
# you could even modify the slices in parallel if you wanted
m_slice <- attach.big.matrix(m_slice_desc)
for (i in 1L:2L) {
for (j in 1L:2L) {
m_slice[i,j] <- m_slice[i,j] * 2
}
}
# return nothing
NULL
}
# just to show that the values were modified in place
for (bm in big_m) { print(bm[,]) }
[,1] [,2]
[1,] 2 6
[2,] 4 8
[,1] [,2]
[1,] 18 22
[2,] 20 24
[,1] [,2]
[1,] 10 14
[2,] 12 16
[,1] [,2]
[1,] 26 30
[2,] 28 32
Если вы не можете / не будете использовать bigmemory
, или если обработка каждого 2-мерного среза слишком быстрая (да, это может быть проблематично для мультиобработки, см. этот ответ ), возможно, вы можете извлечь трехмерные срезы из ваших данных и использовать .noexport
, чтобы копировать только по одному, что-то вроде:
slices_3d <- lapply(1L:2L, function(i) { m[,,,i] })
foreach(slice_3d=slices_3d, .noexport=ls(all.names=TRUE)) %dopar% {
for (j in 1L:2L) {
slice_2d <- slice_3d[,,j]
# do something
}
# return nothing
NULL
}
Я на самом деле не на 100% уверен, что вышеперечисленное помешаеткопирование всего slices_3d
, если нет, возможно, вам придется вручную извлечь подмножества в чанках в основном процессе R (например, slices_3d[1L:num_parallel_workers]
и т. д. каждый раз) и убедиться, что в каждом вызове * экспортируется только один чанк1019 *.