2017-01-09 11 views
0

Ich bin neu in das Konzept der Parallel-ComputingWarum ist es wichtig, die Anzahl der "Kerne" zu erhöhen?

(was ich versuche, auf einem Skript anzuwenden, bei dem eine Schleife für etwa 1000 mal mehrere Regressionsmodelle baut und macht Vorhersagen jeweils Zeit, die auf den Koeffizienten dieser Modelle basiert, die Datensätze sind zu groß und die Modelle beinhalten Dummy-Codes und Gewichte, die den Prozess noch weiter verlangsamen. Daher versuche ich foreach anstelle der 'for'-Schleife anzuwenden.

ich versuche, die doParallel und foreach Bibliotheken und die Anzahl der Kerne mitzu verwenden. Ich habe einen Windows 10-Rechner. Mein Verständnis ist, dass Anrufe wie detectCores() und Sys.getenv('NUMBER_OF_PROCESSORS') wird die Anzahl der „logischen Prozessoren“ und nicht als Kerne zurück:

> detectCores() 
    [1] 4 

My Task Manager zeigt diese Spezifikationen

task manager

Ich habe versucht, ein zu experimentieren Bit mit was ist die "richtige" (?) Anzahl der Kerne sollte ich mit registerDoParallel() einstellen und erkannte, dass es eine beliebige Zahl annehmen wird. Ich experimentierte ein bisschen weiter und fand heraus, dass dies sogar einen Unterschied machen würde. Ich habe das obige Skript von den Entwicklern dieser beiden libraries (S. 3) angepasst, um die serielle bis parallele Ausführung mit verschiedenen Kernen zu vergleichen.

x <- iris[which(iris[,5] != "setosa"), c(1,5)] 
trials <- 10000 

library(foreach) 
library(doParallel) 

#detectCores() 
#Sys.getenv('NUMBER_OF_PROCESSORS') 
registerDoParallel(cores = 4) 
getDoParWorkers() 

ptimes = numeric(15) 
stimes = numeric(15) 

for (i in 1:15) { 
stime <- system.time({ 
    r <- foreach(icount(trials), .combine=cbind) %do% { 
    ind <- sample(100, 100, replace=TRUE) 
    result1 <- glm(x[ind,2]~x[ind,1], family=binomial(logit)) 
    coefficients(result1) 
    } 
})[3] 
stimes[i] = stime 
} 

for (i in 1:15) { 
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] 
ptimes[i] = ptime 
} 

Hier sind die Ergebnisse, gemessen als mittlere Zeit in Sekunden für eine Iteration. Es scheint einen Sweet Spot bei 12 "Kernen" zu haben.

Prozess       mittlere   sd
sequenziellen: 53,8       5,4
"2-core":       32,3   1,9
"4-core":         28,7     2,6
"12-Kern":     22.9     0,5
"24-core":     27,5     1,9

I sogar mittlere Leistung zwischen, sagen wir, "2-core" und "12-Kern" mit t-Tests verglichen und sie sind nicht wegen Zufall.

Meine Fragen sind:

ist es gute Praxis, basierend auf dem oben, um meine Skripte in „12-Core-Modus“ ausgeführt werden, wenn Code, der parallelisiert werden kann?

Ich möchte einen leistungsfähigeren Computer verwenden, um mein Skript auszuführen; Muss ich diesen Vorgang wiederholen, um optimale (= schnellste) Leistung zu finden?

+0

Was wäre, wenn ich Ihnen sagen würde, dass die Verwendung einer optimierten Distribution wie Revolution R die Leistung vervierfachen könnte, ohne dass ein Mitarbeiter benötigt wird? Auf einem Quad-Computer läuft 'svd' auf einem großen Array 7-mal schneller, da die Funktion selbst SIMD-Befehle und Intel-Mathematik-Bibliotheken verwendet. Der Code ist viel sauberer –

+1

Was, wenn ich Ihnen sagte, dass das * nicht * einzigartig zu Revolution R war? Sie haben die Intel MKL mit R seit mindestens einem Jahrzehnt kombinieren können. Und bitte erkläre, welcher Code sauberer ist. –

+0

Wie für Ihre spezielle Frage, CPUs haben viele Tricks außer SIMD, wie Caching, Prefetching Daten und Hyper-Threading. Wenn überhaupt, zeigen Ihre Timings, dass Ihr Code selbst zwei Kerne nicht richtig ausnutzt –

Antwort

1

In der Praxis wird es nett sein, die gleiche Anzahl von Hardware-Kernen (physikalische, 2 in Ihrem Beispiel) als Computing-Threads festzulegen.


Weitere Details:

Wenn die Auslastung rechenintensive ist, mehr Threads (große als Hardware-Kerne) wird die Ressource konkurrieren und die Leistung beeinträchtigen. In einigen Fällen, wie in Ihrem Beispiel, erfordert die Arbeitslast jedoch viel Speicherzugriff pro Berechnungen, so dass mehr Threads den Vorteil haben, die Speicherlatenz zu verbergen. Tatsächlich ist die CPU Latenzorientierung und kann Latenz automatisch verbergen. In deinem Fall können mehr als 2 Threads weitere Verbesserungen erzielen, aber nicht zu viel.

Daher ist es im Vergleich zu der Optimierungszeit (wie viele Threads sollten Sie verwendet werden?) Auf dem anderen System zu jeder Zeit des Laufs besser, # Hardware-Kerne in Ihrem parallelen Computerprogramm zu verwenden.

Eine gute Einführung in die Parallelverarbeitung mit R in here.

+0

Vielen Dank für Ihre Antwort. Nur um zu verdeutlichen und sicherzustellen, dass ich Ihrem Punkt folge, würden Sie den Begriff "Computing-Threads" synonym mit dem Begriff "logische Prozessoren" verwenden? – Tony

+1

@Tony, eigentlich, Computing-Threads ist die Konzepte in Software-Ebene, so dass es bedeutet, wie viele Threads/Verfahren Sie festgelegt haben, wie 2/4/12/24 Sie versucht haben. Auf der anderen Seite bezieht sich "logische/physikalische Prozessoren" auf eine Hardwareressource, die für eine Maschine festgelegt ist, zum Beispiel 2 physikalische Kerne und 4 logische Prozessoren in Ihrer Maschine. Dann überlegen wir, wie man Computer-Threads in Hardware-Cores abbildet. Hier empfehle ich die Strategie von ONE Computing Thread zu ONE physischen Kern. BTW, der ähnliche in [hier] (http: // stackoverflow.com/Fragen/28829300/doparallel-Cluster-vs-Farben/34717363 # 34717363) – Patric

Verwandte Themen