[pyar] Multiprocessing: más lento que el secuencial
Claudio Freire
klaussfreire en gmail.com
Lun Ago 11 23:58:48 ART 2014
2014-08-11 20:49 GMT-03:00 Hernan Grecco <hernan.grecco en gmail.com>:
> 2014-08-11 20:33 GMT-03:00 Franco Nicolas Bellomo <fnbellomo en gmail.com>:
>> Hola gente, como andan?
>> Estoy queriendo empezar a usar python para para resolver algunos
>> calculos que me dan en la carrera (soy estudiante de Lic. en Física).
>> En particular, ahora quiero resolver elementos finitos. Cuando lo
>> resuelvo secuencialmente (implementando numpy) lo calcula bien, pero
>> como el for que recorro es muy grande tarde demasiado. Entonces,
>> importo multiprocessing y anda!! el problema? es que el código
>> paralelisado es más lento que el original, por que?? que estoy
>> haciendo mal?
>
> Hay varias cosas que pueden estar fallando.
>
> En primer lugar, cuando tenes memoria compartida no siempre conviene
> tener muchos procesos porque hay veces que la comunicación entre ellos
> domina. Siempre hay un N por debajo del cual es mejor un solo proceso
> y por arriba te convienen mas. Depende de cuanto cueste hacer una
> operación en relación a cuanto cueste comunicarse. Si estas por debajo
> de ese N, mp va a ser mas lento.
>
> Ademas multiprocessing.Array tiene un Lock y esto es lento. Por
> default, este es un tipo de datos "process-safe". Es decir que podes
> escribir y leer desde cualquier proceso sin temor a corromper los
> datos. (podes desactivar este lock pasando lock=False cuando construis
> el array con el riesgo que eso conlleva.
Es crítico acá el N. A menos que sea más alto que i_steps, te conviene
poner el loop de i_steps adentro de calculo (con el refactoring que
eso conlleva).
Por lo que veo, tu cálculo no es realmente paralelizable de la forma
que lo hacés. Estás haciendo lecturas y escrituras concurrentes en
temp (fijate el cálculo de pos_ini y pos_fin, me parece que algo anda
mal ahí, pero no estoy seguro).
Si el cálculo es vectorizable es probablemente paralelizable, pero tu
método es cuestionable (hacés 1e8 pool.map, que es una bestialidad, a
menos que i_steps sea >> 1e8). Probablemente deberías organizar el
cálculo en un pipeline (por las dependencias de los bloques). Difícil
explicarlo por un mail, pero si dibujás las dependencias de los
bloques vas a ver más claramente cómo tenés que ordenar los cálculos,
y cómo puede paralelizarse.
More information about the pyar
mailing list