2012-03-21 11 views
6

Ciao Sto cercando di utilizzare ddply nella libreria plyr in R, con il pacchetto MC. Non sembra accelerare il calcolo. Questo è il codice che corro:multicore con plyr, MC

require(doMC) 
registerDoMC(4) 
getDoParWorkers() 
##> 4 
test <- data.frame(x=1:10000, y=rep(c(1:20), 500)) 
system.time(ddply(test, "y", mean)) 
    # user system elapsed 
    # 0.015 0.000 0.015 
system.time(ddply(test, "y", mean, .parallel=TRUE)) 
    # user system elapsed 
    # 223.062 2.825 1.093 

Qualche idea?

+3

A seconda dei calcoli effettivi che si stanno eseguendo, il pacchetto 'data.table' potrebbe davvero velocizzarli. Per tutte le sue virtù, l'implementazione 'split-apply-combine' nel pacchetto 'plyr' è in realtà piuttosto lenta, mentre' data.table' è innanzitutto progettata per la velocità. (Se sei incuriosito, cerca SO per qualcosa come '[r] [data.table] plyr' per ottenere molti possibili punti di partenza). –

+0

Grazie Josh, darò un'occhiata. – Alex

risposta

10

La funzione mean funziona troppo rapidamente rispetto ai costi di comunicazione richiesti per distribuire le sezioni divise in ciascun nucleo e recuperare i risultati.

Questo è un "problema" comune incontrato con il calcolo distribuito. Si aspettano che tutto vada più veloce perché dimenticano che ci sono costi (comunicazione tra i nodi) e benefici (usando più core).

Qualcosa di specifico per l'elaborazione parallela in plyr: solo la funzione viene eseguita su più core. La suddivisione e la combinazione sono ancora fatti su un singolo core, quindi la funzione che stai applicando dovrebbe essere molto intensiva dal punto di vista computazionale per vedere un vantaggio quando si usano le funzioni plyr in parallelo.

+0

Questo è solo un esempio. Il vero quadro dati che ho sono 4 milioni di righe con 2000 gruppi. Il codice con parallelo e senza resi nello stesso tempo. – Alex

+1

@Alex: Se il tuo data.frame è enorme, la tua funzione dovrà essere molto più intensiva dal punto di vista computazionale, perché la maggior parte del tempo trascorso in 'ddply' sta per essere suddiviso e combinato, non applicando la funzione. –

+0

vedo ... quindi la parte che distribuisce è l'effettiva applicazione della funzione .. la suddivisione lo fa ancora su 1 core? – Alex

1

Continuazione per la risposta di Joshua, c'è una correzione se si desidera velocizzare questa operazione. È ispirato all'ideologia di Ridurre la mappa e ho fatto un POC su un set di dati campione qualche tempo fa.

Ho usato la libreria nevicata, credo che si possa lavorare anche con doMC.

# On my phone, please pardon typos/bugs 

test <- data.frame(x=1:1000000, y=rep(c(1:20), 500)) 

testList = list() 
testList[[1]] <- test[c(1:250000),] 
testList[[2]] <- test[c(250001:500000),] 
testList[[3]] <- test[c(500001:750000),] 
testList[[4]] <- test[c(750001:1000000),] 

# Write a function for the above - Need to find optimum number of splits 

sfInit(parallel = TRUE, cpus=4) 
sfCluster(plyr) 
meanList = sfClusterSpplyLB(testList, function(x) ddply(test, "y", mean)) 

sfStop() 

aggregate(meanList, by=list(y), FUN=mean) 

Questo potrebbe aiuto, dato che ora stiamo facendo la routine split-combinano in modo distribuito. Questo funziona per mezzi quando la dimensione delle divisioni sono le stesse, funziona per somme, min/max, conteggio ecc. OK, ma ci sono alcune operazioni che non possiamo usare per questo.