Я часто получаю несколько вложенных циклов foreach
, и иногда при написании общих функций (например, для пакета) нет уровня, на котором можно было бы распараллелить. Есть ли способ выполнить то, что описывает макет ниже?
foreach(i = 1:I) %if(I < J) `do` else `dopar`% {
foreach(j = 1:J) %if(I >= J) `do` else `dopar`% {
# Do stuff
}
}
Кроме того, есть ли способ определить, зарегистрирован ли параллельный бэкэнд, чтобы я мог избежать ненужных предупреждений? Это было бы полезно как при проверке пакетов перед отправкой CRAN, так и для того, чтобы не беспокоить пользователей, использующих R на одноядерных компьютерах.
foreach(i=1:I) %if(is.parallel.backend.registered()) `dopar` else `do`% {
# Do stuff
}
Спасибо за ваше время.
Редактировать: Большое спасибо за все отзывы о ядрах и рабочих, и вы правы в том, что лучший способ справиться с приведенным выше примером - это переосмыслить всю установку. Я предпочел бы что-то вроде ниже идеи triu
, но это по сути тот же момент. И, конечно, это можно сделать с помощью параллельной tapply
, как предложил Джорис.
ij <- expand.grid(i=1:I, j=1:J)
foreach(i=ij$I, j=ij$J) %dopar% {
myFuction(i, j)
}
Однако, пытаясь упростить ситуацию, из-за которой возникла эта тема, я пропустил некоторые важные детали. Представьте, что у меня есть две функции analyse
и batch.analyse
, и лучший уровень для распараллеливания может отличаться в зависимости от значений n.replicates
и n.time.points
.
analyse <- function(x, y, n.replicates=1000){
foreach(r = 1:n.replicates) %do% {
# Do stuff with x and y
}
}
batch.analyse <- function(x, y, n.replicates=10, n.time.points=1000){
foreach(tp = 1:time.points) %do% {
my.y <- my.func(y, tp)
analyse(x, my.y, n.replicates)
}
}
Если n.time.points > n.replicates
, имеет смысл распараллеливать в batch.analyse
, но в противном случае имеет смысл распараллеливать в analyse
. Любые идеи о том, как справиться с этим? Можно ли как-то обнаружить в analyse
, если распараллеливание уже произошло?