Probleme mit foreach-Parallelisierung

Ich versuche zu vergleichen Parallelisierung Optionen. Speziell, ich Vergleiche den standard SNOW und mulitcore Implementierungen von denen doSNOW oder doMC und foreach. Als ein Beispiel problem, ich bin zu illustrieren, central limit theorem durch die Berechnung der Mittel der gezogenen Proben aus einer standard-normal-Verteilung, viele Male. Hier ist die standard-code:

CltSim <- function(nSims=1000, size=100, mu=0, sigma=1){
  sapply(1:nSims, function(x){
    mean(rnorm(n=size, mean=mu, sd=sigma))
  })
}

Hier ist die SNOW Umsetzung:

library(snow)
cl <- makeCluster(2)

ParCltSim <- function(cluster, nSims=1000, size=100, mu=0, sigma=1){
  parSapply(cluster, 1:nSims, function(x){
    mean(rnorm(n=size, mean=mu, sd=sigma))
  })
}

Nächsten, die doSNOW Methode:

library(foreach)
library(doSNOW)
registerDoSNOW(cl)

FECltSim <- function(nSims=1000, size=100, mu=0, sigma=1) {
  x <- numeric(nSims)
  foreach(i=1:nSims, .combine=cbind) %dopar% {
    x[i] <- mean(rnorm(n=size, mean=mu, sd=sigma))
  }
}

Bekomme ich folgende Ergebnisse:

> system.time(CltSim(nSims=10000, size=100))
   user  system elapsed 
  0.476   0.008   0.484 
> system.time(ParCltSim(cluster=cl, nSims=10000, size=100))
   user  system elapsed 
  0.028   0.004   0.375 
> system.time(FECltSim(nSims=10000, size=100))
   user  system elapsed 
  8.865   0.408  11.309 

Den SNOW Implementierung Rasiert ab etwa 23% der Rechenzeit im Vergleich zu einem unparallelized laufen (time Einsparungen größer als die Anzahl der Simulationen zu erhöhen, wie wir es erwarten würden). Die foreach Versuch eigentlich erhöht Laufzeit um einen Faktor von 20. Außerdem, wenn ich das ändern %dopar% zu %do% und überprüfen Sie die unparallelized version der Schleife, es dauert über 7 Sekunden.

Darüber hinaus berücksichtigen wir die multicore Paket. Die simulation geschrieben multicore ist

library(multicore)
MCCltSim <- function(nSims=1000, size=100, mu=0, sigma=1){
  unlist(mclapply(1:nSims, function(x){
    mean(rnorm(n=size, mean=mu, sd=sigma))
  }))
}

Bekommen wir eine noch bessere Verbesserung der Geschwindigkeit als SNOW:

> system.time(MCCltSim(nSims=10000, size=100))
   user  system elapsed 
  0.924   0.032   0.307 

Starten eines neuen R-Sitzung, können wir versuchen, die foreach Umsetzung mit doMC statt doSNOW Aufruf

library(doMC)
registerDoMC()

dann läuft FECltSim() wie oben, noch zu finden

> system.time(FECltSim(nSims=10000, size=100))
   user  system elapsed 
  6.800   0.024   6.887 

Dies ist "nur" eine 14-fache Erhöhung gegenüber den nicht-parallelisierte Laufzeit.

Fazit: Meine foreach code ist nicht effizient läuft entweder unter doSNOW oder doMC. Irgendeine Idee warum?

Dank,
Charlie

InformationsquelleAutor Charlie | 2011-02-15
Schreibe einen Kommentar