No estoy seguro de si esto cuenta más como un problema del sistema operativo, pero pensé en preguntar aquí en caso de que alguien tenga alguna idea del final de Python.
He estado tratando de paralelizar un for
ciclo de CPU pesado usando 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 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 de que pueda ejecutar estos procesos en diferentes núcleos?
Respuestas:
Después de buscar más en Google, encontré la respuesta aquí .
Resulta que ciertos módulos de Python (
numpy
,scipy
,tables
,pandas
,skimage
desorden ...) con afinidad central en la importación. Por lo que puedo decir, este problema parece ser causado específicamente por su vinculación con bibliotecas OpenBLAS multiproceso.Una solución alternativa es restablecer la afinidad de la tarea utilizando
Con esta línea pegada después de las importaciones del módulo, 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
numpy
el rendimiento, aunque esto probablemente sea específico de la máquina y la tarea.Actualizar:
También hay dos formas de deshabilitar el comportamiento de restablecimiento de afinidad de CPU de OpenBLAS. En tiempo de ejecución puede usar la variable de entorno
OPENBLAS_MAIN_FREE
(oGOTOBLAS_MAIN_FREE
), por ejemploO, alternativamente, si está compilando OpenBLAS desde la fuente, puede deshabilitarlo permanentemente en el momento de la compilación editando el
Makefile.rule
para contener la líneafuente
psutil
.Python 3 ahora expone los métodos para establecer directamente la afinidad
fuente
Esto parece ser un problema común con Python en Ubuntu, y no es específico para
joblib
:Sugeriría experimentar con afinidad de CPU (
taskset
).fuente
Python on Ubuntu
Esto implica que funciona sin problemas en Windows y otros sistemas operativos. ¿Lo es?