tutorial multiplicar matrices libreria functions español python linux numpy multiprocessing blas

python - multiplicar - ¿Por qué el multiprocesamiento usa solo un núcleo después de importar numpy?



numpy functions (3)

No estoy seguro de si esto cuenta más como un problema de sistema operativo, pero pensé que podría preguntar aquí en caso de que alguien tenga alguna idea del final de Python.

He estado intentando paralelizar un ciclo pesado for CPU con joblib , pero encuentro que en lugar de que cada proceso de trabajo se asigne a un núcleo diferente, termino con todos ellos asignados al mismo núcleo y sin ganancia de rendimiento.

Aquí hay un ejemplo muy trivial ...

from joblib import Parallel,delayed import numpy as np def testfunc(data): # some very boneheaded CPU work for nn in xrange(1000): for ii in data[0,:]: for jj in data[1,:]: ii*jj def run(niter=10): data = (np.random.randn(2,100) for ii in xrange(niter)) pool = Parallel(n_jobs=-1,verbose=1,pre_dispatch=''all'') results = pool(delayed(testfunc)(dd) for dd in data) if __name__ == ''__main__'': run()

... y esto es lo que veo en htop mientras se ejecuta este script:

Estoy ejecutando Ubuntu 12.10 (3.5.0-26) en una computadora portátil con 4 núcleos. Claramente, joblib.Parallel está generando procesos separados para los diferentes trabajadores, pero ¿hay alguna forma en que pueda hacer que estos procesos se ejecuten en diferentes núcleos?


Después de buscar en Google, encontré la respuesta here .

Resulta que ciertos módulos de Python ( numpy , scipy , tables , pandas , skimage ...) se skimage con la afinidad central en la importación. Por lo que puedo decir, este problema parece ser específicamente causado por su vinculación con bibliotecas multiproceso OpenBLAS.

Una solución alternativa es restablecer la afinidad de la tarea usando

os.system("taskset -p 0xff %d" % os.getpid())

Con esta línea pegada después de que el módulo importa, mi ejemplo ahora se ejecuta en todos los núcleos:

Mi experiencia hasta ahora ha sido que esto no parece tener ningún efecto negativo en el numpy de numpy , aunque esto probablemente sea específico de la máquina y de la tarea.

Actualizar:

También hay dos formas de desactivar el comportamiento de reinicio de afinidad de la CPU de OpenBLAS. En tiempo de ejecución, puede usar la variable de entorno OPENBLAS_MAIN_FREE (o GOTOBLAS_MAIN_FREE ), por ejemplo

OPENBLAS_MAIN_FREE=1 python myscript.py

O, como alternativa, si está compilando OpenBLAS desde el origen, puede desactivarlo permanentemente en el momento de la compilación editando el Makefile.rule para que contenga la línea.

NO_AFFINITY=1



Python 3 ahora expone los methods para establecer directamente la afinidad

>>> import os >>> os.sched_getaffinity(0) {0, 1, 2, 3} >>> os.sched_setaffinity(0, {1, 3}) >>> os.sched_getaffinity(0) {1, 3} >>> x = {i for i in range(10)} >>> x {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} >>> os.sched_setaffinity(0, x) >>> os.sched_getaffinity(0) {0, 1, 2, 3}