124 votes

Ce qui détermine si différents processus de Python sont assignés aux noyaux identiques ou différents ?

Je ne suis pas sûr que cela compte plus comme un OS de problème, mais j'ai pensé que je voudrais poser ici au cas où quelqu'un a un aperçu de l'Python fin des choses.

J'ai essayé de paralléliser un PROCESSEUR lourds- for boucle à l'aide de joblib, mais je trouve qu'au lieu de chaque processus de travail d'être affecté à une autre base, je me retrouve avec chacun d'entre eux étant affecté à la même base et pas de gain de performance.

Voici un exemple 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 en htop alors que ce script est en cours d'exécution:

htop

Je suis sur Ubuntu 12.10 (3.5.0-26) sur un ordinateur portable avec 4 cœurs. Clairement joblib.Parallel de fraye des processus séparés pour les différentes catégories de travailleurs, mais est-il une manière que je peux faire de ces processus s'exécutent sur différents cœurs?

144voto

ali_m Points 7185

Après quelques recherches sur google j'ai trouvé la réponse ici.

Il s'avère que certains modules Python (numpy, scipy, tables, pandas, skimage...) mess avec le noyau de l'affinité de l'importation. Aussi loin que je peux dire, ce problème semble être spécifiquement provoquée par eux de se lier à des multithread OpenBLAS bibliothèques.

Une solution de contournement est de rétablir la tâche d'affinité à l'aide de

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

Avec cette ligne de coller après le module importations, mon exemple fonctionne maintenant sur tous les cœurs:

htop_workaround

Mon expérience a été que cela ne semble pas avoir d'effets négatifs sur l' numpy's de performance, même si c'est probablement la machine et spécifique à la tâche .

Mise à jour:

Il y a aussi deux façons de désactiver l'affinité CPU-réinitialisation de comportement de OpenBLAS lui-même. Au moment de l'exécution, vous pouvez utiliser la variable d'environnement OPENBLAS_MAIN_FREE (ou GOTOBLAS_MAIN_FREE), par exemple

OPENBLAS_MAIN_FREE=1 python myscript.py

Ou sinon, si vous êtes à la compilation OpenBLAS à partir des sources, vous pouvez désactiver définitivement au moment de la construction, par l'édition de l' Makefile.rule de contenir la ligne

NO_AFFINITY=1

12voto

NPE Points 169956

Cela semble être un problème commun avec Python sur Ubuntu, et n'est pas spécifique à l' joblib:

Je suggère d'expérimenter avec l'affinité CPU (taskset).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X