R - Как распараллелить цикл for, выполняющий симуляции Монте-Карло?

Я пытаюсь понять, как распараллелить некоторый код из «интеллектуального анализа данных с помощью R - обучения с тематическими исследованиями», чтобы он работал быстрее на моем MacBook Pro. Конкретный рассматриваемый код ниже. Код в основном использует одни и те же данные (DS) и применяет шесть разных учащихся (например, svm, nnet для регрессии и классификации и т. Д.) С небольшим количеством вариантов.

Полный код находится ЗДЕСЬ (внизу, в модели " оценка и отбор ».

for(td in TODO) {
  assign(td,
     experimentalComparison(
       DSs,         
       c(
         do.call('variants',
                 c(list('singleModel',learner=td),VARS[[td]],
                   varsRootName=paste('single',td,sep='.'))),
         do.call('variants',
                 c(list('slide',learner=td,
                        relearn.step=c(60,120)),
                   VARS[[td]],
                   varsRootName=paste('slide',td,sep='.'))),
         do.call('variants',
                 c(list('grow',learner=td,
                        relearn.step=c(60,120)),
                   VARS[[td]],
                   varsRootName=paste('grow',td,sep='.')))
         ),
        MCsetts)
     )
  # save the results
  save(list=td,file=paste(td,'Rdata',sep='.'))
}

Большая часть информации о распараллеливании, которую я нахожу, кажется более применимой к таким вещам, как «применить», когда одна и та же функция применяется к разным подмножествам данных. Этот код делает противоположное - разные функции применяют одни и те же данные.

Было бы лучше распараллелить внешний цикл FOR, чтобы код внутри выполнялся для нескольких учащихся одновременно, в отличие от параллельного выполнения кода внутри цикла, чтобы различные подходы к работе с окнами применялись параллельно для одного учащегося.

На моем MacBook выполнение одной итерации занимает чуть более 2 часов, где только 2 ядра, кажется, что-то делают (два других просто бездействуют). Фактический код из ссылки установлен на 20 итераций ... Было бы здорово использовать мои незанятые ядра, чтобы уменьшить это


r
person Andrew Dempsey    schedule 09.01.2012    source источник
comment
Для обширных симуляций Монте-Карло R, вероятно, будет слишком медленным, независимо от того, как вы его распараллеливаете. Простой способ получить небольшое (в 1-5 раз) ускорение - использовать функцию компилятора для байтовой компиляции вашей основной функции (например, variantsCMP <- cmpfun(variants), но для гораздо более быстрого ускорения лучше всего использовать скомпилированный язык. C ++ можно легко реализовать в R через пакет Rcpp.   -  person Sacha Epskamp    schedule 09.01.2012
comment
Быстрый и грязный способ выполнять параллельные вычисления - использовать lapply(1:N, some_function), где N - количество раз, которое вы хотите вычислить some_function. В Unix / Linux вы можете заменить lapply на mclapply из пакета parallel (при условии, что у вас более одного ядра). Если вы работаете в Windows, обратите внимание на пакет snow.   -  person Jason Morgan    schedule 10.01.2012
comment
Итак, что-то вроде lapply (1: 6, code_as_function ())? Где функция использует все глобальные переменные, а не все, что ей передается? Казалось бы, это имеет смысл, поскольку переменная TODO - это просто список более компактных имен, которые можно применить ко всему набору данных.   -  person Andrew Dempsey    schedule 10.01.2012


Ответы (1)


В непараллельном случае передать функции в цикл lapply просто.

lapply(c(mean, sum), function(f) f(1:5))

Это несколько разных систем для параллельного программирования с R. В следующем примере используется snow.

library(snow)
cl <- makeCluster(c("localhost","localhost"), type = "SOCK")
clusterApply(cl, c(mean, sum), function(f) f(1:5))
stopCluster(cl)

В каждом случае вы должны получить одинаковый ответ!

person Richie Cotton    schedule 09.01.2012
comment
Я на Mac, так что сейчас как Тахо Калифорния - снега нет - person Andrew Dempsey; 10.01.2012
comment
На CRAN есть двоичный файл Mac для snow. Вы уверены, что это не сработает? cran.r-project.org/web/packages/snow/index. html - person Richie Cotton; 10.01.2012
comment
В любом случае, какая параллель заставляет вас использовать, не имеет значения для концепции: вам нужна функция, подобная lapply, и передайте ей список функций (имена функций также будут работать). - person Richie Cotton; 10.01.2012
comment
О ... Извините, я думал, что снег - это только окна. Я попробую, как только напишу приведенный выше код - person Andrew Dempsey; 10.01.2012
comment
Чтобы выбрать параллельный пакет, подумайте о том, чтобы прочитать www.jstatsoft.org/v31/i01/paper пару лет назад, но исчерпывающий. - person Richie Cotton; 10.01.2012
comment
Спасибо за ссылку на статью. Я прочитаю это. По сути, я ищу «образец» того, как распараллеливать код, подобный приведенному выше, который я могу многократно использовать в разных проектах. Я ищу не сверхнадежность и скорость, а удобное ускорение - person Andrew Dempsey; 10.01.2012