2016-04-07 29 views
6

Sto cercando di decidere se utilizzare il multiprocessing o il threading e ho imparato alcuni bit interessanti sullo Global Interpreter Lock. In questo simpatico blog post, sembra che il multithreading non sia adatto per le attività impegnate. Tuttavia, ho anche appreso che alcune funzionalità, come I/O o numpy, non sono influenzate dal GIL.Perché i calcoli del numpy non sono influenzati dal blocco dell'interprete globale?

Qualcuno può spiegare perché, e come posso scoprire se il mio codice (probabilmente piuttosto intorpidito) sarà adatto per il multithreading?

risposta

11

Molti calcoli di numpy non sono interessati dal GIL, ma non tutti.

Mentre nel codice che non richiede l'interprete Python (ad esempio librerie C) è possibile rilasciare in modo specifico GIL - consentendo l'esecuzione di altro codice che dipende dall'interprete. Nella base numpy C le macro NPY_BEGIN_THREADS e NPY_END_THREADS vengono utilizzate per delimitare blocchi di codice che consentono il rilascio di GIL. Puoi vederli in this search of the numpy source.

Il NumPy C API documentation ha ulteriori informazioni sul supporto di threading. Annotare le macro aggiuntive NPY_BEGIN_THREADS_DESCR, NPY_END_THREADS_DESCR e NPY_BEGIN_THREADS_THRESHOLDED che gestiscono il rilascio condizionale GIL, in base all'array dtypes e alla dimensione dei loop.

La maggior parte delle funzioni fondamentali rilasciare il GIL - per esempio Universal Functions (ufunc) farlo as described:

fintanto che non gli array di oggetti sono coinvolti, il Global Interpreter Lock Python (GIL) viene rilasciato prima di chiamare i loop. Viene riacquisito se necessario per gestire le condizioni di errore.

Per quanto riguarda il proprio codice, il source code for NumPy is available. Controlla le funzioni che usi (e le funzioni che chiamano) per le macro precedenti. Si noti inoltre che il vantaggio in termini di prestazioni dipende in gran parte da per quanto tempo viene rilasciato il codice GIL - se il codice viene costantemente rilasciato in/out da Python non si vedranno miglioramenti significativi.

L'altra opzione è semplicemente testarlo. Tuttavia, tenere presente che le funzioni che utilizzano le macro condizionali GIL possono presentare un comportamento diverso con array di piccole e grandi dimensioni. Pertanto, un test con un set di dati di piccole dimensioni potrebbe non rappresentare una rappresentazione accurata delle prestazioni per un'attività più ampia.

Esistono alcune informazioni aggiuntive sull'elaborazione parallela con numpy disponibile on the official wiki e un post utile su Python GIL in generale over on Programmers.SE.

+1

Grazie, questa è una risposta davvero utile! – Lisa