Ich bin mir nicht sicher, ob dies mehr als Betriebssystemproblem zählt, aber ich dachte, ich würde hier fragen, falls jemand einen Einblick in das Python-Ende der Dinge hat.
Ich habe versucht, eine CPU-schwere for
Schleife mithilfe von zu parallelisieren joblib
, aber ich stelle fest, dass nicht jeder Arbeitsprozess einem anderen Kern zugewiesen wird, sondern alle demselben Kern zugewiesen werden und kein Leistungsgewinn erzielt wird.
Hier ist ein sehr triviales Beispiel ...
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()
... und hier ist, was ich sehe, htop
während dieses Skript ausgeführt wird:
Ich verwende Ubuntu 12.10 (3.5.0-26) auf einem Laptop mit 4 Kernen. Es joblib.Parallel
ist klar, dass separate Prozesse für die verschiedenen Worker erzeugt werden. Gibt es jedoch eine Möglichkeit, diese Prozesse auf verschiedenen Kernen auszuführen?
Antworten:
Nach etwas mehr googeln fand ich die Antwort hier .
Es stellt sich heraus , dass bestimmte Python - Module (
numpy
,scipy
,tables
,pandas
,skimage
...) mess mit Kern Affinität zu importieren. Soweit ich das beurteilen kann, scheint dieses Problem speziell dadurch verursacht zu werden, dass sie mit Multithread-OpenBLAS-Bibliotheken verknüpft sind.Eine Problemumgehung besteht darin, die Aufgabenaffinität mithilfe von zurückzusetzen
Nachdem diese Zeile nach dem Import des Moduls eingefügt wurde, wird mein Beispiel jetzt auf allen Kernen ausgeführt:
Bisher habe ich die Erfahrung gemacht, dass dies keine negativen Auswirkungen auf
numpy
die Leistung zu haben scheint , obwohl dies wahrscheinlich maschinen- und aufgabenspezifisch ist.Aktualisieren:
Es gibt auch zwei Möglichkeiten, das Verhalten zum Zurücksetzen der CPU-Affinität von OpenBLAS selbst zu deaktivieren. Zur Laufzeit können Sie beispielsweise die Umgebungsvariable
OPENBLAS_MAIN_FREE
(oderGOTOBLAS_MAIN_FREE
) verwendenWenn Sie OpenBLAS aus dem Quellcode kompilieren, können Sie es alternativ beim Erstellen dauerhaft deaktivieren, indem Sie das bearbeiten
Makefile.rule
, um die Zeile zu enthaltenquelle
psutil
.Python 3 stellt jetzt die Methoden zum direkten Festlegen der Affinität bereit
quelle
Dies scheint ein häufiges Problem mit Python unter Ubuntu zu sein und ist nicht spezifisch für
joblib
:Ich würde vorschlagen, mit der CPU-Affinität zu experimentieren (
taskset
).quelle
Python on Ubuntu
Dies bedeutet, dass es unter Windows und anderen Betriebssystemen problemlos funktioniert. Ist es?