Domanda

Così ho appena finito di guardare questo discorso sul Python globale Interpreter Lock (GIL) http://blip.tv/ file / 2232410 .

Il succo è che la GIL è un buon progettazione di sistemi unipolari (pitone lascia sostanzialmente trasporto del filo / pianificazione fino al sistema operativo). Ma che questo può seriamente ritorcersi su sistemi multi-core e si finisce con IO fili intensivi essendo fortemente bloccati da fili CPU intensive, le spese di commutazione di contesto, il problema Ctrl-C [*] e così via.

Quindi, dal momento che la GIL ci limita ad eseguire fondamentalmente un programma Python su una CPU il mio pensiero è perché non accettare questo e semplicemente utilizzare taskset su Linux per impostare l'affinità del programma a una certa core / CPU sul sistema (in particolare in una situazione con più applicazioni Python in esecuzione su un sistema multi-core)?

Quindi, in ultima analisi, la mia domanda è questa: qualcuno ha provato ad utilizzare taskset su Linux con applicazioni Python (in particolare durante l'esecuzione di più applicazioni su un sistema Linux in modo che più core possono essere utilizzati con le applicazioni di uno o due Python legati ad un nucleo specifico) e in caso affermativo quali sono stati i risultati? vale la pena di fare? Fa le cose peggiori per alcuni carichi di lavoro? Ho intenzione di fare questo e verificare il lavoro svolto (in pratica se il programma richiede più o meno tempo per l'esecuzione) ma ci piacerebbe sentire da altri come alle vostre esperienze.

Aggiunta: David Beazley (il ragazzo dando il discorso nel video linkato) ha sottolineato che le estensioni qualche C / C ++ rilasciare manualmente il blocco GIL e se queste estensioni sono ottimizzati per il multi-core (cioè l'analisi dei dati scientifici o numerico / etc .) allora piuttosto che ottenere i benefici della multi-core per macinare numeri l'estensione sarebbe effettivamente paralizzato in quanto è limitata ad un singolo core (quindi potenzialmente rallentare il vostro programma in modo significativo). D'altra parte, se non si utilizza le estensioni di questo tipo

Il motivo per cui non sto usando il modulo multiprocessing è che (in questo caso) parte del programma è fortemente rete di I / O bound (richieste HTTP) in modo da avere un pool di thread di lavoro è un ottimo modo per spremere prestazioni da una scatola da quando un thread spara una richiesta HTTP e quindi dal momento che è in attesa di I / O dà il GIL e un altro thread può fare è cosa, in modo che una parte del programma può facilmente eseguire 100 + thread senza danneggiare la CPU molto e lasciare mi realtà uso della larghezza di banda di rete disponibile. Per quanto riguarda Stackless Python / etc non sono eccessivamente interessato a riscrivere il programma o sostituire il mio stack Python (la disponibilità sarebbe anche una preoccupazione).

[*] Solo il filo conduttore in grado di ricevere i segnali per cui se si invia un CTRL-C l'interprete Python in fondo cerca di ottenere il thread principale per eseguire in modo che possa gestire il segnale, ma dal momento che non controlla direttamente quale thread è gestito (questo è lasciato al sistema operativo) si dice in sostanza il sistema operativo per tenere discussioni di commutazione finché alla fine colpisce il thread principale (che se siete sfortunati può richiedere del tempo).

È stato utile?

Soluzione

Non ho mai sentito di nessuno usando taskset per un guadagno di prestazioni con Python. Non significa che non possa succedere nel tuo caso, ma sicuramente pubblicare i risultati in modo che altri possano criticare i vostri metodi di benchmarking e di fornire la convalida.

Personalmente, però, vorrei disaccoppiare le nostre discussioni di I / O dai fili della CPU bound utilizzando una coda di messaggi. In questo modo il front-end è ora completamente rete di I / O bound (alcuni con interfaccia HTTP, alcune con interfaccia coda di messaggi) ed è ideale per la vostra situazione filettatura. Poi la CPU processi intensi possibile utilizzare multiprocessing o semplicemente essere singoli processi in attesa di lavoro per arrivare sulla coda di messaggi.

A lungo termine si potrebbe anche prendere in considerazione la sostituzione del I filettato / O front-end con Twisted o qualche cosa come eventlets perché, anche se non vogliono aiutare le prestazioni dovrebbero migliorare la scalabilità. Il tuo back-end è ora già scalabile perché è possibile eseguire il coda di messaggi su qualsiasi numero di macchine + CPU a seconda delle necessità.

Altri suggerimenti

Un'altra soluzione è: http://docs.python.org/library/multiprocessing.html

Nota 1:. Questo è non di una limitazione del linguaggio Python, ma di implementazione CPython

Nota 2: Per quanto riguarda l'affinità, il sistema operativo non dovrebbe avere un problema di fare che si

.

Una soluzione interessante è l'esperimento riportato da Ryan Kelly sul suo blog: http://www.rfk.id.au/blog/entry/a-gil-adventure-threading2/

I risultati sembrano molto soddisfacenti.

Ho trovato la seguente regola empirica sufficiente nel corso degli anni: Se i lavoratori sono dipendenti qualche stato condiviso, io uso un processo di multiprocessing per core (CPU legato), e per core un pool correzione di thread di lavoro (I / O bound). Il sistema operativo si prenderà cura di assigining i diversi processi Python ai nuclei.

Il Python GIL è per interprete Python. Ciò significa che il solo per evitare problemi con esso, mentre facendo multiprocessore semplicemente iniziando multipli interpreti (cioè con processi separati invece di fili per la concorrenza) e quindi utilizzando qualche altro IPC primitive per la comunicazione tra i processi (come prese). Detto questo, il GIL non è un problema quando si utilizzano fili con il blocco chiamate di I / O.

Il problema principale della GIL come detto in precedenza è che non è possibile eseguire 2 diversi thread di codice python allo stesso tempo. Un filo di blocco su una chiamata di blocco I / O è bloccata e quindi non executin codice python. Ciò significa che non stia bloccando il GIL. Se si dispone di due compiti CPU intensive in discussioni Python separate, è lì che il GIL uccide multi-processing in Python (solo l'attuazione CPython, come sottolineato in precedenza). Poiché la GIL ferma CPU # 1 di eseguire un filo pitone mentre CPU # 0 è occupato in esecuzione l'altro thread pitone.

sino a quando la GIL viene rimosso dal pitone, co-routine possono essere usati al posto di fili. Ce l'ho su buona autorità che questa strategia è stata implementata da due di successo start-up, utilizzando greenlets in almeno un caso.

Questa è una domanda piuttosto vecchio, ma dal momento che ogni volta che ricerca su informazioni relative al pitone e le prestazioni su sistemi multi-core questo post è sempre sulla lista dei risultati, non vorrei che lo scorso davanti a me un non condivido i miei pensieri.

È possibile utilizzare il modulo multiprocessing che, invece di creare thread per ogni attività, si crea un altro processo di CPython compier interpretare il codice. Sarebbe l'applicazione per sfruttare i sistemi multicore. L'unico problema che vedo in questo approccio è che si avrà un notevole sovraccarico con la creazione di un intero nuovo stack processo sulla memoria. ( http://en.wikipedia.org/wiki/Thread_(computing)#How_threads_differ_from_processes )

modulo

Python Multiprocessing: http://docs.python.org/dev/library/multiprocessing.html

"Il motivo per cui non sto usando il modulo multiprocessing è che (in questo caso) parte del programma è fortemente rete di I / O bound (richieste HTTP) in modo da avere un pool di thread di lavoro è un ottimo modo per spremere prestazioni da una scatola ... "

A proposito di questo, credo che si può avere anche un pool di processo troppo: http://docs.python.org/dev/library/multiprocessing.html#using-a-pool-of-workers

Att, Leo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top