Я новичок в параллельном программировании и собрал бит о R из разных (иногда противоречивых) источников. Я унаследовал какой-то код и попытался его распараллелить, я думаю, что правильная параллелизация данных.ClusterMap в R на разветвленном кластере намного медленнее, чем mapply. Что еще я могу попробовать?
Задача требует некоторых вычислений по нескольким индивидам (фаза 1), затем вычисляемые величины используются для вычисления некоторой характеристики популяции (фаза 2). Мы делаем это для цикла над некоторым заданным числом итераций. У меня есть подозрение (соединяя биты, которые я прочитал), что вычисления из фазы 1 вызывают изменение объекта, хранящего результаты, которые делают вычисление, страдают от некоторого времени ожидания, вызванного (нежелательным) копированием объектов. Результатом является выполнение программы с использованием clusterMap с гораздо большим системным временем, чем непараллелизированная версия кода с использованием mapply.
Расчеты требуют много уровней вызовов функций. Я попытался дать представление о структуре кода в небольшом рабочем примере ниже.
require(parallel)
## define the two phases of the computation
phase1.top.level<- function(x,y){second.level(x,y)}
## Functions call other functions.
phase1.second.level<- function(x,y){ third.level(x,y) }
phase1.third.level<- function(x,y){ result<- x^2-2*y*x; result }
## define the function that performs the second phase of the computation
second.phase<-function(input,x,y) {input+x+y}
## Assemble these functions into an algorithm
multi.phase.comp<- function(input,x,y){
input<-phase1.top.level(x,y)
output<-second.phase(input,x,y)
}
### Call the function with inputs
x<-seq(1:100)
y<-seq(1:100)
input<-rep(1,100)
## Time the function executed for the vector inputs using clusterMap from the parallel package
system.time({
no_cores<-5
c1<- makeCluster(no_cores,type="FORK")
out<- clusterMap(cl=c1, multi.phase.comp, input, x, y)
stopCluster(c1)
})
### One execution of this (on an old laptop) gave
### user system elapsed
### 0.055 0.163 0.973
## Regrettably, the effort to parallelise wasn't justified as mapply is faster:
system.time({
out2<- mapply(multi.phase.comp, input, x, y)
})
#### This shows much less system and elapsed time
#### user system elapsed
#### 0.009 0.002 0.030
Любые предложения о том, как ускорить мой код? Будет ли я лучше с кластерами сокетов для этого типа приложений?
Проблемы с почти никаким временем вычисления не стоит выполнять параллельно, поскольку время вычислений намного меньше, чем накладные расходы на отправку задач и получение результатов от работников. Если задачи в вашей реальной задаче занимают даже 0,1 секунды для выполнения, параллельная версия должна бить mapply. Но нет смысла пытаться улучшить производительность этой игрушечной проблемы, так как вы никогда не сможете бить 0,03 секунды. –
@SteveWeston действительный код гораздо более задействован, и слишком длинный и запутанный, чтобы служить иллюстрацией. Вот реализация фактического времени работы: Открытие кластера в одном из нижних уровней функции дает система пользователя истекшее 12,219 1,390 29,283 так что вы можете видеть время, прошедшее гораздо больше времени (не хорошо) обработки Но если я использую кластер в двух местах, я получаю пользовательскую систему, истекшую 11.029 1.763 71.022 Использование только mapply дает время в 5-7 секунд. –
Что произойдет, если вы используете 'mcmapply (multi.phase.comp, input, x, y, mc.cores = no_cores)' (без каких-либо makeCluster, stopCluster)? –