2013-05-24 5 views
10

Ich versuche, das DoParallel und Foreach-Paket zu verwenden, aber ich habe eine Verringerung der Leistung mit dem Bootstrapping-Beispiel in der Anleitung gefunden hier CRANpage.Ich versuche, mit doParallel und foreach, aber keine Verbesserung zu starten

library(doParallel) 
library(foreach) 
registerDoParallel(3) 
x <- iris[which(iris[,5] != "setosa"), c(1,5)] 
trials <- 10000 
ptime <- system.time({ 
    r <- foreach(icount(trials), .combine=cbind) %dopar% { 
    ind <- sample(100, 100, replace=TRUE) 
    result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit)) 
    coefficients(result1) 
    } 
    })[3] 
ptime 

Dieses Beispiel gibt 56.87 zurück.

Wenn ich die dopar in nur do ändern, um sie sequentiell anstatt parallel auszuführen, gibt sie 36.65 zurück.

Wenn ich registerDoParallel(6) tun, erhält es die parallele Zeit bis 42.11 ist aber immer noch langsamer als sequentiell. registerDoParallel(8) wird 40.31 immer noch schlechter als sequenziell.

Wenn ich trials auf 100.000 erhöhen, dann dauert der sequentielle Lauf 417.16 und der parallele Lauf mit 3 Arbeitern dauert 597.31. Bei 6 parallel arbeitenden Mitarbeitern dauert es 425.85.

Mein System ist

  • Dell Optiplex 990

  • Windows 7 Professional 64-Bit-

  • 16GB RAM

  • Intel i-7-2600 3,6 GHz Quad- Kern mit Hyperthreading

Mache ich hier etwas falsch? Wenn ich die am meisten gekünstelte Sache mache, die ich mir vorstellen kann (indem ich den Berechnungscode durch Sys.sleep(1) ersetze), dann bekomme ich eine tatsächliche Reduktion, die eng proportional zur Anzahl der Arbeiter ist. Ich frage mich, warum das Beispiel im Guide die Leistung für mich verringert, während es für sie die Dinge beschleunigt hat?

+6

Dies ist ein fast-FAQ: Sie testen mit Sys.sleep() war in Ordnung, und es zeigt, dass das Einrichten der Threads mehr Zeit als das Berechnen benötigt. Versuchen Sie, die Größe des Problems, d. H. Probe (10000) zu erhöhen, und Sie werden eine Verbesserung sehen. Ihre Maschine hat jedoch nur 4 Kerne, also funktioniert nichts über 4 Kerne hinaus. Ich habe nie einen Effekt von Hyperthreading gesehen (unter Windows und ohne spezielle R-Compiles) –

+0

@DieterMenne: Ihr Punkt darüber, dass es FAQish ist, ist gut gemacht. Die Tatsache, dass das Beispiel des Führers mir durch mich keinen Nutzen gebracht hat. Sie hatten Recht, dass eine Erhöhung der Stichprobengröße mich dahin bringen würde, wo Parallelität eine Verbesserung darstellt. Danke auch für den Tipp zum HT. Ich habe einen Test mit 4 gegen 8 Mitarbeitern gemacht und es war im Grunde die gleiche Zeit. –

Antwort

9

Das zugrunde liegende Problem ist, dass attach für jede Taskausführung auf den Arbeitern des PSOCK-Clusters ausführt, um die exportierten Variablen dem Paketsuchpfad hinzuzufügen. Dies behebt verschiedene Problembereiche, kann jedoch die Leistung erheblich beeinträchtigen, insbesondere bei Aufgaben mit kurzer Dauer und großen Mengen exportierter Daten. Diese tut nicht geschehen unter Linux und Mac OS X mit Ihrem Beispiel, da sie mclapply statt clusterApplyLB verwenden, aber es wird auf allen Plattformen passieren, wenn Sie explizit einen PSOCK-Cluster registrieren.

Ich glaube, dass ich herausgefunden habe, wie man die Aufgabe Scoping Probleme in einer anderen Art und Weise zu lösen, die die Leistung nicht weh, und ich arbeite mit Revolution Analytics das Update in die nächste Version von doParallel zu bekommen und doSNOW , die auch das gleiche Problem hat.

Sie können Chunking mithilfe von Aufgabe, um dieses Problem zu umgehen:

ptime2 <- system.time({ 
    chunks <- getDoParWorkers() 
    r <- foreach(n=idiv(trials, chunks=chunks), .combine='cbind') %dopar% { 
    y <- lapply(seq_len(n), function(i) { 
     ind <- sample(100, 100, replace=TRUE) 
     result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit)) 
     coefficients(result1) 
    }) 
    do.call('cbind', y) 
    } 
})[3] 

Dies pro Arbeitnehmer nur eine Aufgabe führt, so dass jeder Arbeiter führt nur attach einmal, anstatt trials/3 mal.Es führt auch zu weniger, aber größeren Socket-Operationen, die auf den meisten Systemen effizienter ausgeführt werden können, aber in diesem Fall ist das kritische Problem attach.

+0

mit 4 Arbeitern dauerte dies 9,2 Sekunden. Als ich chunks = 1 gemacht habe, brauchte ich 28.18 –

+0

. Ich wollte den Betreuer mailen, um sie wissen zu lassen, aber es ist Revolution Analytics und ich möchte nicht von den Verkäufern getroffen werden. –

+2

@DeanMacGregor Mach dir keine Sorgen: Ich habe sie bereits kontaktiert, besonders seit ich entdeckt habe, was das eigentliche zugrunde liegende Problem ist und glaube, dass ich es behoben habe. Ich arbeite gerade mit Revolution, um es in der nächsten Version von doSNOW und doParallel zu reparieren. –