2016-12-26 2 views
1

Я хотел бы получить информацию о том, как структурирован мой код ниже. Хотелось бы знать, нужно ли его организовать другим способом, чтобы выполнить быстрее. В частности, должен ли я использовать foreach и dopar по-разному в вложенных циклах. В настоящее время внутренний цикл является основной частью работы (ddply между 1-8 переменными разбиения, каждый из которых имеет уровни 10-200), и это то, что я выполняю параллельно. Я просто оставил детали кода для простоты.Оптимизация вложенного foreach dopar в R

Любые идеи? Мой код, как описано ниже, действительно работает, но он занимает несколько часов на 6-ядерном, 41-гигабайтном компьютере. Набор данных не такой большой (< 20k записей).

for(m in 1:length(Predictors)){ # has up to three elements in the vector 

    # construct the dataframe based on the specified predictor 
    # subset the original dataframe based on the breakdown variables, outcome, predictor and covariates 

    for(l in 1:nrow(pairwisematrixReduced)){ # this has 1-6 rows;subset based on correct comparison groups 

    # some code here 

    cl <- makeCluster(detectCores()) 
    registerDoParallel(cl) 

    for (i in 1:nrow(subsetting_table)){ # this table has about 50 rows 

     # this uses the columns specified by k in the glm; the prior columns will be used as breakdown variables 
     # up to 10 covariates 
     result[[length(result) + 1]] <- foreach(k = 11:17, .packages=c('plyr','reshape2', 'fastmatch')) %dopar% { 

     ddply( 
      df, 
      b, # vector of breakdown variables 
      function(x) { 

      # run a GLM and manipulate the output 

      ,.parallel = TRUE) # close ddply 
     } # close k loop -- set of covariates 
    } # close i loop -- subsetting table 
    } #close l -- group combinations 
} # close m loop - this is the pairwise predictor matrix 

stopCluster(cl) 
result <- unlist(result, recursive = FALSE) 
tmp2<-do.call(rbind.fill, result) 
+0

Я рекомендую запустить следующие команды и прочитать о различии между '% dopar%' и '%:%'. 'vignette (" foreach ")' и 'vignette (" inested ")' – manotheshark

+0

foreach находится в пределах i – Josh

+1

Я пропустил этот 'foreach', но я бы рекомендовал прочитать упомянутую выше виньетку. Будет проще писать как 'foreach', так и' ddply' как 'foreach' с помощью'% dopar' и другого '%:%'. Виньетка говорит о преимуществах параллельного внутреннего и внешнего циклов. Вам нужно будет проверить свой собственный код, поскольку он зависит от данных, но становится так же легко, как замена '% dopar%' и '%:%' между двумя 'foreach'. – manotheshark

ответ

4

скопирован из vignette("nested")

3% Использование:% с% dopar%

Когда распараллеливание вложенным для петель, всегда есть вопрос о том, какой цикл распараллелить. Стандартный совет ...

Вы также используете foreach%dopar% вместе с ddply и .parallel=TRUE. С шестиядерным процессором (и предположительно гиперпотоком) означает, что блок foreach начнет 12 сред, а затем ddply начнет 12 сред в каждом из них для 144 одновременных сред. Значение foreach должно быть изменено на %do%, чтобы соответствовать вашим текстам вопросов о параллельном запуске внутреннего цикла. Или сделать его более чистым, измените оба значения на foreach и используйте %dopar% для одной петли и %:% для другого.

Смежные вопросы