3

Ich erstelle, multipliziere und summiere dann alle Elemente zweier großer Matrizen in numpy. Ich mache das ein paar hundert Mal mit zwei Methoden, einer Schleife und mit Hilfe des multiprocessing Moduls (siehe unten).Was fehlt mir in Python-Multiprocessing/Multithreading?

def worker_loop(n): 
    for i in n: 
    mul = np.sum(np.random.normal(size=[i,i])*np.random.normal(size=[i,i])) 

def worker(i): 
    mul = np.sum(np.random.normal(size=[i,i])*np.random.normal(size=[i,i])) 

n = range(100,300) 

pool = ThreadPool(2) 
pool.map(worker, n) 
pool.close() 
pool.join() 

worker_loop(n) 

Messen der Zeit erzählt, dass die Schleife ist schneller als multiprocessing. Ich habe auch versucht, die threading Modul ohne Erfolg (dann las ich, dass dies eine schlechte Idee war, mehr lesen here)

Ich begann diese mit Multithreading zu experimentieren, weil ich Bilder konvertieren müssen, Etiketten, Zeichen-Boxen, ... in tfrecords. Dafür studiere ich eine Datei von Tensorflow/inception (wenn du willst bleibe build_imagenet_data.py, line 453). Ich glaube, dass hier Multithreading funktioniert, deshalb benutzen sie es.

Mit diesen Worten kann meine Frage gestellt werden wie folgt

  • was soll ich in meinem Code fehlt; Kann man mit kleinen Modifikationen etwas erreichen?
  • funktioniert das Beispiel von Anfang an, weil Tensorflow in C++ und CUDA geschrieben wird?
  • Wann empfiehlt es sich Multiprocessing oder Multithreading mit numpy, tensorflow und ähnlichem zu verwenden?

Antwort

3

Es gibt immer etwas Aufwand (Synchronisation, Datenaufbereitung, Datenkopien und Co.).

Aber: Da ein gutes Setup, Ihre Matrix-Vektor-und Vektor-Vektor-Operationen in numpy bereits multithreaded sind, mit BLAS (das ist der Stand der Technik Standard ist überall einschließlich numpy verwendet, Matlab und wahrscheinlich tensorflow der CPU- Backend; es gibt jedoch verschiedene Implementierungen).

Wenn also BLAS alle Ihre Kerne belegen kann (einfacher mit großen Dimensionen), sehen Sie nur den Overhead.

Und ja, Tensorflow in seinem Kern wird von mindestens einem von C/C++/Fortran plus BLAS für sein CPU-Backend und einigen Cuda-libs beim Targeting von GPU implementiert. Dies bedeutet auch, dass die Kernalgorithmen als Gradienten- und Optimierungsrechnungen niemals extern parallelisiert werden sollten (in 99,9% aller Anwendungsfälle).

+0

Und um die zweite Frage zu beantworten, ist es nicht ratsam, Multiprocessing oder Multithreading mit numpy oder Tensorflow zu verwenden, es sei denn, Sie machen einige schwere I/O-gebundene Arbeit. Tensorflow unterstützt diese Kontingenz tatsächlich über Warteschlangenläufer. Wie bei den tatsächlichen Berechnungen sind sowohl Tensorflow als auch Numpy bereits in der Lage, die Last auf jeden Kern zu verteilen, den Sie haben. –

+1

Soweit ich weiß, verwendet Tensorflow Eigen, das standardmäßig seine eigenen (hochoptimierten) Low-Level-Routinen verwendet. Das ändert natürlich nichts an Saschas Antwort. – dseuss

+0

@dseuss Interessant. Es scheint, dass Sie Recht haben, obwohl es Unterstützung für all diese BLAS-libs gibt und neuere Benchmarks zeigen, dass diese schneller sind (was erwartet wird), trotz Eigens offiziellen FAQ (mit veralteten Benchmarks und etwas auf Single-Core beschränkt). – sascha