2016-08-06 60 views
5

Ich verwende die Bibliothek parallel in R, um einen großen Datensatz zu verarbeiten, auf den ich komplexe Operationen anwende.paralleles Lesen und Verarbeiten von Dateien in R

Aus Gründen einen reproduzierbaren Code bereitzustellen, können Sie unter einem einfacheren Beispiel finden:

#data generation 
dir <- "C:/Users/things_to_process/" 

setwd(dir) 
for(i in 1:800) 
{ 
    my.matrix <- matrix(runif(100),ncol=10,nrow=10) 

    saveRDS(my.matrix,file=paste0(dir,"/matrix",i)) 
} 

#worker function 
worker.function <- function(files) 
{ 
    files.length <- length(files) 
    partial.results <- vector('list',files.length) 

    for(i in 1:files.length) 
    { 
     matrix <- readRDS(files[i]) 
     partial.results[[i]] <- sum(diag(matrix)) 
    } 

    Reduce('+',partial.results) 
} 


#master part 
cl <- makeCluster(detectCores(), type = "PSOCK") 

file_list <- list.files(path=dir,recursive=FALSE,full.names=TRUE) 

part <- clusterSplit(cl,seq_along(file_list)) 
files.partitioned <- lapply(part,function(p) file_list[p]) 

results <- clusterApply(cl,files.partitioned,worker.function) 

result <- Reduce('+',results) 

Wesentlichen statt in einer verschachtelten Weise geschehen würde, wenn versucht, ich frage mich, Dateien parallel zu lesen. Und wenn dieser Engpass die erwartete Leistung parallel laufender Aufgaben reduzieren würde?

Wäre es besser, wenn ich zuerst alle Matrizen auf einmal in einer Liste lese und dann Teile dieser Liste an jeden Kern sende, damit er verarbeitet werden kann? Was wäre, wenn diese Matrizen viel größer wären, wäre ich in der Lage, alle in einer Liste auf einmal zu laden?

+0

Ich sehe keinen Grund, zuerst alle Daten zu lesen und dann zu verarbeiten. Ihre Pipeline sieht für mich ziemlich effizient aus (normalerweise verwende ich etwas Ähnliches). Wenn Sie viele Dateien verarbeiten, wird die Systemlast nach einiger Zeit gleichmäßig. Was ist Ihrer Meinung nach ein Engpass? Berechnungen oder I/O? –

+1

@DmitriySelivanov Ich profilierte meine Worker-Funktion, und der Engpass ist weitgehend auf die readRDS() - Funktion zurückzuführen. Ich denke, dass dies geschieht, weil Arbeiter warten müssen, bis andere die Datei vollständig gelesen haben, damit sie anfangen können zu lesen. Ich bin mir nicht sicher, wie das Betriebssystem parallele Lesungen behandelt, und ich frage mich, ob das Laden aller Dateien Daten im Speicher würde die Leistung verbessern – Imlerith

+0

Das Problem kann in Kompression sein. Verwenden Sie eine Komprimierung? ('saveRDS' wendet es standardmäßig an). Aber ich schalte es normalerweise aus und die Dinge werden viel Meister. –

Antwort

4

Anstatt die matrix in einer separaten RDS-Datei zu speichern, haben Sie versucht, eine list von N Matrizen in jeder Datei zu speichern, wobei N die Nummer ist, die von einem einzelnen Arbeiter verarbeitet wird?

Dann sieht die worker.function wie:

worker.function <- function(file) { 
    matrix_list <- readRDS(file) 
    partial_results <- lapply(matrix_list, function(mat) sum(diag(mat))) 
    Reduce('+',partial.results) 
} 

Sie sollten einige Zeit auf der I/O sparen und vielleicht sogar auf die Berechnung durch einen for mit einem lapply ersetzen.

+0

Ich verwende tatsächlich k-fache Kreuzvalidierung mit k als Eingangsvariable. Das bedeutet, dass ich mit Ihrer Lösung die Falten in den Dateien neu speichern müsste, abhängig von der Aufteilung der Falten. Dies erhöht den Aufwand für die Berechnungen. Ich wollte eigentlich nur die Konsequenzen verstehen, wenn ich versuche, Dateien parallel zu lesen (wie würde das Betriebssystem das handhaben, und wenn das zu Engpässen führen könnte, warum?), Dann frage ich in der zweiten Frage nach einer Alternative zum Laden aller Daten Speicher (ich dachte an Hadoop und ob dies ein Fall wäre, in dem die Verwendung eines DFS gerechtfertigt ist) – Imlerith

+0

Wird in Ihrem Code nicht jede der Dateien in 'file_list' nur von einem Arbeiter gelesen? In diesem Fall sollten nicht mehrere Mitarbeiter versuchen, die gleiche Datei zu lesen. In Bezug auf die k-fache Validierung könnte es in Abhängigkeit von dem Wert von "k" möglich sein, die Daten in k-Dateien (eine Datei nach Stück) zu speichern, die kein erneutes Speichern erfordern würden. –