2012-07-02 2 views
1

У меня есть следующий кусок кода, который я хотел бы работать с двигателем DoMC:Еогеасп - dopar не начинают рабочим

who_wins<-function(probs_a,probs_b,delta_order=0,delta_down=0){ 
    #browser() 
    team_a<-runif(5,0,1) 
    team_b<-runif(5,0,1) 
    sya<-syb<-0 
    for(i in 1:5){ 
    for(j in 1:2){ 
     if(j==1){ 
     if(sya<syb){ 
      team_a[i]<-(1-delta_down)*team_a[i] 
     } 
     team_a[i]<-(1-(i-1)*delta_order)*team_a[i] 
     sya<-sya+(team_a[i]<probs_a[i]) 
     } 
     else{ 
     if(syb<sya){ 
      team_b[i]<-(1-delta_down)*team_b[i] 
     } 
     team_b[i]<-(1-(i-1)*delta_order)*team_b[i] 
     syb<-syb+(team_b[i]<probs_b[i]) 
     } 
    } 
    } 
    if(sya>syb){ 
    return(1) 
    } 
    else if(sya<syb){ 
    return(2) 
    } 
    else { 
    return(0) 
    } 
} 

library(doMC) 
registerDoMC(8) 

probs_a<-seq(.6,.8,length.out=5) 
probs_b<-probs_a[5:1] 
nsim<-20000 

results<-foreach(icount(nsim), .combine=c) %dopar% { 
    return(who_wins(probs_a,probs_b)) 
} 

Проблема в том, что через пару секунд после начала первого рабочий, движок пытается запустить оставшиеся. Я вижу всплеск во всех процессорах, но все они быстро умирают, даже первые. Затем запускается новый процесс, а оставшийся код запускается через этого одинокого работника.

Я пробовал с различными частями кода, и двигатель работает отлично. Но с этим конкретным рутином это не так.

Может ли кто-нибудь сказать мне, что происходит? Заранее спасибо.

+0

Я предлагаю вам включить код для 'who_wins' функции, особенно если это просто. Затем другие могут просто захватить ваш код, чтобы начать экспериментировать и исследовать. – MvG

+0

Готово. Thx для предложения. – jcredberry

ответ

3

Добавление Sys.sleep(0.01) внутри вашей петли, я вижу, что все 8 процессов «заняты» этим. После их завершения основной процесс остается занятым в течение некоторого времени. Я предполагаю, что накладные расходы по сбору данных из отдельных процессов и их объединению в один результат аналогичны масштабу, чем фактическая выгода от параллельного вычисления. Если вы просто измените «вычисление» на return(1), вы увидите, что это занимает примерно столько же времени, сколько и вычисление, поэтому время не затрачивается на рабочую нагрузку, а собирает результат.

Ни .inorder=FALSE, либо использование doParallel вместо doMC изменить это. Тем не менее, я хотел бы рассмотреть эту проблему в foreach пакете, поскольку mclapply имеет значительно меньше накладные расходы:

result <- unlist(mclapply(1:nsim, function(i) { 
    return(who_wins(probs_a, probs_b)) 
}, mc.cores=8)) 
+0

Спасибо MvG. Безупречная идея! Я не знал о накладных проблемах цикла foreach. – jcredberry

+0

Я тоже не собирался стать крупным фанатом 'foreach'. Вы хотите сообщить об этой проблеме сторонникам 'foreach'? Возможно, есть что-то, что они могут с этим поделать. – MvG

+0

Я тоже. Я использовал почти все. У меня есть только электронная почта для документов, у вас есть другие? – jcredberry