2012-03-21 10 views
6

Hola, estoy tratando de usar ddply en la biblioteca plyr en R, con el paquete MC. No parece estar acelerando el cálculo. Este es el código que ejecuto:multinúcleo 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 

¿Alguna idea?

+3

Dependiendo de los cálculos reales que está realizando, el paquete 'data.table' realmente podría acelerarlos. A pesar de todas sus virtudes, la implementación 'split-apply-combine' en el paquete 'plyr' es realmente bastante lenta, mientras que' data.table' está diseñado principalmente para la velocidad. (Si está intrigado, busque SO para algo como '[r] [data.table] plyr' para obtener muchos puntos de inicio posibles). –

+0

Gracias Josh, voy a echar un vistazo. – Alex

Respuesta

10

La función mean opera demasiado rápido en relación con los costos de comunicación necesarios para distribuir las secciones divididas a cada núcleo y recuperar los resultados.

Este es un "problema" común que las personas se topan con la informática distribuida. Esperan que todo funcione más rápido porque olvidan que hay costos (comunicación entre los nodos) y beneficios (usando múltiples núcleos).

Algo específico para el procesamiento paralelo en plyr: solo la función se ejecuta en varios núcleos. La división y la combinación todavía se realizan en un solo núcleo, por lo que la función que está aplicando debería ser muy intensiva en términos de computación para ver un beneficio al usar funciones plyr en paralelo.

+0

Esto es solo un ejemplo. El marco de datos real que tengo es de 4 millones de filas con 2000 grupos. El código con paralelo y sin devuelve el mismo tiempo. – Alex

+1

@Alex: si su data.frame es enorme, entonces su función tendrá que ser mucho más intensiva desde el punto de vista computacional porque la mayor parte del tiempo invertido en 'ddply' se dividirá y combinará, sin aplicar la función. –

+0

veo ... entonces la parte que distribuye es la aplicación real de la función ... ¿la división aún lo hace en 1 núcleo? – Alex

1

Continuando con la respuesta de Joshua, hay una solución si desea acelerar esta operación. Está inspirado en la ideología Map-reduce y hace un tiempo hice un POC en un conjunto de datos de muestra.

Utilicé la biblioteca de nevadas: creo que también se puede trabajar 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) 

Esta fuerza ayuda que, teniendo en cuenta que ahora estamos haciendo la rutina dividida combinar de una forma distribuida. Esto funciona para los medios cuando el tamaño de las divisiones es el mismo, funciona para sumas, mín./Máx., Recuento, etc. están bien, pero hay algunas operaciones para las que no podemos usar esto.

Cuestiones relacionadas