Je ne sais pas si cela compte davantage comme un problème de système d'exploitation, mais j'ai pensé que je demanderais ici au cas où quelqu'un aurait un aperçu de la fin de Python.
J'ai essayé de paralléliser une for
boucle lourde en CPU joblib
, mais je trouve qu'au lieu d'attribuer chaque processus de travail à un noyau différent, je me retrouve tous affectés au même noyau et sans gain de performance.
Voici un exemple très 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()
... et voici ce que je vois htop
pendant l'exécution de ce script:
J'exécute Ubuntu 12.10 (3.5.0-26) sur un ordinateur portable avec 4 cœurs. Il joblib.Parallel
est clair que des processus séparés sont créés pour les différents travailleurs, mais y a-t-il un moyen de faire exécuter ces processus sur différents cœurs?
Réponses:
Après quelques recherches sur Google, j'ai trouvé la réponse ici .
Il se trouve que certains modules Python (
numpy
,scipy
,tables
,pandas
,skimage
...) pagaille avec une affinité de base à l' importation. Pour autant que je sache, ce problème semble être spécifiquement causé par leur liaison avec des bibliothèques OpenBLAS multithread.Une solution de contournement consiste à réinitialiser l'affinité de la tâche à l'aide de
Avec cette ligne collée après l'importation du module, mon exemple fonctionne maintenant sur tous les cœurs:
Mon expérience jusqu'à présent a été que cela ne semble pas avoir d'effet négatif sur
numpy
les performances de, bien que cela soit probablement spécifique à la machine et à la tâche.Mettre à jour:
Il existe également deux façons de désactiver le comportement de réinitialisation d'affinité du processeur d'OpenBLAS lui-même. Au moment de l'exécution, vous pouvez utiliser la variable d'environnement
OPENBLAS_MAIN_FREE
(ouGOTOBLAS_MAIN_FREE
), par exempleOu bien, si vous compilez OpenBLAS à partir de la source, vous pouvez le désactiver définitivement au moment de la construction en éditant le
Makefile.rule
pour contenir la lignela source
psutil
.Python 3 expose maintenant les méthodes pour définir directement l'affinité
la source
Cela semble être un problème courant avec Python sur Ubuntu, et n'est pas spécifique à
joblib
:Je suggérerais d'expérimenter l'affinité CPU (
taskset
).la source
Python on Ubuntu
Cela implique qu'il fonctionne sans problème sur Windows et d'autres systèmes d'exploitation. C'est ça?