2015-10-15 15 views
8

Capisco che cPython abbia un GIL in modo che lo script non possa essere eseguito su più core senza utilizzare il modulo multiprocessing. Ma c'è qualcosa per fermare le funzioni incorporate come l'ordinamento utilizzando più core? Non capisco la struttura di cPython ma penso che la domanda che sto ponendo sia 'sono funzioni incorporate come ordinamento, qualsiasi ed elenco di descrizioni effettivamente al di sotto del GIL?cPython usa più core per funzioni integrate come sort, any, all?

risposta

5

Il cPython GIL ha a che fare solo con l'abilitazione di un singolo thread per eseguire bytecode all'interno di un processo - non è correlato alla CPU non astratta.

Detto questo, a partire da ora, a meno che non stiate chiamando qualcosa da biforcarsi/utilizzare più processi o il vostro sistema operativo/hardware sta intercettando le chiamate e facendo questo per voi (altamente improbabile), vedrete tutte le vostre operazioni core a singola CPU.

Le funzioni integrate implementate in C si verificano "sotto GIL" in quanto sono chiamate più dirette alle API sottostanti, ma l'inserimento di argomenti e dati per tali funzioni avviene all'interno di GIL, poiché si utilizza bytecode per leggere e scrivere.

Per inciso, se si desidera comprendere meglio la relazione cPython con il suo host, suggerirei il seguente high-level official overview e/o the PDF slides and the playground that I wrote for a conference.

+0

GIL non è solo un byte di codice. I conteggi di riferimento devono essere aggiornati solo sotto GIL, il che significa che roba che manipola i conteggi dei riferimenti non può rilasciare GIL quando lo fa. 'any',' all' e 'sorted' sono eseguiti interamente sotto GIL, poiché in tutti si sta verificando un sacco di manipolazione del conteggio dei riferimenti, anche se il codice byte non viene necessariamente eseguito (ad es. nel caso di' ordinati' usando tipi incorporati in cui anche i confronti sono allo strato C). Ci sono stati test sull'utilizzo di operazioni atomiche per mantenere il conteggio dei ref e ha sempre rallentato CPython in modo inaccettabile. – ShadowRanger

+1

Non sono sicuro di aver affermato che GIL _only_ ha a che fare con il bytecode - stavo indirizzando l'attenzione della domanda sul "front-end" di Python - sort/any/list. Passare argomenti a quelli che si verificano nel codice byte. –

+0

Non l'hai fatto, ma il problema principale che impedisce l'uso di 'sorted' /' any'/'all' dal rilascio di GIL (anche se potevano garantire che gli elementi in elaborazione non vengano mai eseguiti codice byte per i confronti, generando valori , applicare predicati, ecc.). La domanda dell'OP riguardava la capacità di parallelizzare e le restrizioni GIL, non quello che è il byte code e ciò che non lo è. I built-in sono sotto il livello del codice byte, ma non sono liberi da GIL, perché anche se il lavoro che facevano poteva essere garantito non eseguire mai il codice byte (non può), anche il codice interamente in C usando oggetti Python ha bisogno del GIL. – ShadowRanger

2

Nessuna delle funzioni menzionate si parallelizza automaticamente. In generale, i thread che si generano in modo silenzioso sono considerati di scarsa qualità nella maggior parte dei linguaggi (questo sta cambiando, ma è ancora visto solo in linguaggi funzionali puri in cui la sicurezza del thread è integrata nella progettazione); generare molti thread senza dare un avvertimento è come si ottengono errori misteriosi quando l'utente tenta di lanciare i propri thread e ottenere errori transitori dovuti ad avere troppi thread in esecuzione. Quindi, anche se il GIL non era un problema, non avrebbe senso farlo.

Detto questo, il GIL è lì per proteggere gli interni dell'interprete e copre qualsiasi scenario in cui i conteggi di riferimento vengono manipolati, il che è costante; con rare eccezioni, non è possibile fare alcun lavoro significativo su PyObject* s (che è quello che tutti i tipi di livello Python sono rappresentati come in C) con GIL mantenuto. In genere, i built-in Python rilasciano il GIL solo per operazioni di blocco (I/O, in attesa di blocchi, ecc.); è solo nelle estensioni C di terze parti (e ctypes) in cui la versione di GIL è normale, poiché in questi casi convertono gli PyObject interamente in tipi di livello C, rilascia il GIL ora che nessun conteggio dei riferimenti o altri interni vengono toccati, esegui lavoro costoso, riacquisire GIL e convertire i risultati da tipi di livello C in oggetti di livello Python.

Problemi correlati