2016-04-07 10 views
6

Ich versuche zu entscheiden, ob ich Multiprocessing oder Threading verwenden sollte, und ich habe einige interessante Bits über die Global Interpreter Lock gelernt. In diesem netten blog post scheint Multithreading nicht für vielbeschäftigte Aufgaben geeignet zu sein. Ich habe jedoch auch gelernt, dass einige Funktionen wie I/O oder Numpy von der GIL nicht beeinflusst werden.Warum sind Berechnungen mit Nummern nicht von der globalen Interpretersperre betroffen?

Kann mir jemand erklären, warum und wie ich herausfinden kann, ob mein (wahrscheinlich ziemlich numberlastiger) Code für Multithreading geeignet ist?

Antwort

11

Viele numpy Berechnungen sind von der GIL nicht betroffen, aber nicht alle.

Während in Code, der nicht den Python-Interpreter (z. B. C-Bibliotheken) erfordert, ist es möglich, die GIL - Freigabe anderen Code, der vom Interpreter abhängt, weiter ausgeführt werden. In der Codebase von Numpy C werden die Makros NPY_BEGIN_THREADS und NPY_END_THREADS verwendet, um Code-Blöcke zu begrenzen, die die Freigabe von GIL erlauben. Sie können diese in this search of the numpy source sehen.

Die NumPy C API documentation enthält weitere Informationen zur Threading-Unterstützung. Beachten Sie die zusätzlichen Makros NPY_BEGIN_THREADS_DESCR, NPY_END_THREADS_DESCR und NPY_BEGIN_THREADS_THRESHOLDED, die die bedingte GIL-Freigabe verarbeiten, abhängig vom Array dtypes und der Größe der Schleifen.

Die meisten Kernfunktionen lassen Sie die GIL - zum Beispiel Universal Functions (ufunc) tun so as described:

solange keine Objekt-Arrays beteiligt sind, wird die Python Globale Interpreter Lock (GIL), bevor freigegeben, um die Schleifen aufrufen. Es wird, falls erforderlich, erneut erworben, um Fehlerbedingungen zu behandeln.

In Bezug auf Ihren eigenen Code, der source code for NumPy is available. Überprüfen Sie die Funktionen, die Sie verwenden (und die Funktionen, die sie aufrufen) für die oben genannten Makros. Beachten Sie auch, dass der Leistungsvorteil stark davon abhängt, dass wie lange die GIL veröffentlicht wird - wenn Ihr Code ständig in/aus Python fällt, werden Sie nicht viel von einer Verbesserung sehen.

Die andere Möglichkeit ist es nur zu testen. Beachten Sie jedoch, dass Funktionen, die konditionale GIL-Makros verwenden, bei kleinen und großen Arrays möglicherweise ein unterschiedliches Verhalten aufweisen. Ein Test mit einem kleinen Datensatz kann daher keine genaue Darstellung der Leistung für eine größere Aufgabe sein.

Es gibt einige zusätzliche Informationen zur parallelen Verarbeitung mit numpy verfügbar on the official wiki und einen nützlichen Beitrag über die Python GIL im Allgemeinen over on Programmers.SE.

+1

Vielen Dank, das ist eine sehr hilfreiche Antwort! – Lisa