|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
[Python] Multiprocessing e condivisione di oggetti read-only
Salve, ho un problema con Python.
Ho implementato un algoritmo genetico usando Deap, ma questo non è importante. L'algoritmo funziona, purtroppo però la versione multi-processo ha un problema, consuma molta più memoria della versione single-process. Immagino che l'utilizzo esagerato della memoria sia dovuto al fatto che viene allocata memoria per ogni processo così da poter caricare gli oggetti che poi verranno usati. Questo è sbagliato perché gli oggetti che vengono usati vengono soltanto letti dai diversi processi, quindi potrebbero benissimo essere condivisi così da risparmiare memoria. Questa è la struttura del codice che ho scritto. Dovrei passare l'oggetto Dataset ai singoli processi. Codice:
def evaluate(individual, dataset=None):
penalty = dataset.compute(individual)
return penalty
def initialize():
dataset = dataset(file1, file2)
pool = multiprocessing.Pool()
toolbox.register("map", pool.map)
toolbox.register("evaluate", evaluate, dataset=dataset)
return toolbox, dataset
def main():
toolbox, dataset = initialize()
dataset.data = some_training_set
fitnesses = toolbox.map(toolbox.evaluate, population)
dataset.data = some_validation_set
fitnesses = toolbox.map(toolbox.evaluate, population)
Codice:
class Dataset:
def __init__(self, file1, file2):
self.data = read(file1)
self.dict = loadpickle(file2)
def compute(self, individual):
for row in self.data
# some stuff reading row and self.dict
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Purtroppo è un casino. Forse questa soluzione su StackOverflow può aiutarti.
EDIT. Ecco un altro articolo interessante sull'argomento. EDIT2: altri due risposte (qui e qui) su SO, correlate, ma la musica mi sembra la stessa.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys Ultima modifica di cdimauro : 16-01-2015 alle 21:11. |
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Ti ringrazio per i link, però avevo già dato un'occhiata su Stack Overflow, ma da solo non sono riuscito a trovare una soluzione. Ho da poco iniziato a studiare Python e non sono molto esperto di multi-processing.
Possibile che è così complicato? In fondo, devo semplicemente leggere quegli oggetti, non ho problemi di sincronizzazione o altro... Implementare una versione multithread sarebbe possibile? Avrebbe le stesse performance? Da quello che leggo in giro non sembra essere molto conveniente... Ultima modifica di oNaSsIs : 16-01-2015 alle 21:23. |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Col multithreading risolvi sicuramente, perché non hai bisogno di farti copia alcuna, come avviene invece normalmente col multiprocessing (a meno di usare il suo tipo Array, come hai potuto leggere, ma con tutte le problematiche del caso).
Soprattutto se si tratta di oggetti "a sola lettura", col multithreading non hai alcun problema di condivisione. Il problema del modulo threading è, però, che fa uso di un solo core, come penso tu sappia, causa presenza della famigerata GIL. Se il tuo algoritmo è I/O bound, non penso che ciò sia un problema. Anzi, così viene sfruttato per bene il singolo core. Ma se devi fare "number crunching", allora ti scontrerai con questa enorme limitazione. In alternativa, se potessi suddividere i dati in parti diverse (file o mmap), e fargliele leggere poi ai singoli processi, probabilmente potresti anche risolvere. E' una tecnica che ho usato tempo addietro, quando dovevo sfruttare tutti i core, ma distribuire un certo insieme di numeri: li ho partizionati in un certo modo, e poi dato in pasto ogni blocco a un ben preciso processo.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Trattandosi di un algoritmo genetico devo valutare la bontà di una soluzione e per fare ciò devo leggere dei dati. Per ottimizzare ho pensato di fare queste valutazioni in parallelo perché indipendenti. Credo che per avere un notevole incremento delle performance ho bisogno per forza del multiprocessing.
Ma è davvero così complicato riuscire a leggere un csv e condividerlo tra i processi? Non è che riusciresti ad aiutarmi? Io ho letto di tutto in giro, multiprocessing.Value, multiprocessing.Array, Manager.... ma davvero non riesco a venirne a capo. EDIT: Qui ad esempio suggeriscono di usare il Manager. Ultima modifica di oNaSsIs : 16-01-2015 alle 21:57. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Se i dati del CSV li puoi partizionare, potresti risolvere in questo modo, fornendo a ogni processo del pool soltanto ciò che deve processare.
Ho lavorato poco col multiprocessing, per cui oltre a ciò che ho scritto non mi viene in mente altro usando questo strumento. Un'altra soluzione potrebbe essere quella di usare mmap e la classica fork per creare i vari processi. Nella documentazione del modulo mmap c'è qualche esempio in merito. Oltre a questo... I give-up.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#7 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Non posso partizionare il file.
Ti ringrazio lo stesso per l'aiuto. |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Ho visto adesso il tuo edit. Il Manager sembra poter risolvere il tuo problema.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12869
|
Teoricamente se sei sotto un sistema operativo tipo Linux, e il multi-processing sfrutta il forking, finché non tocchi le pagine di memoria che contengono i dati questi non vengono copiati dal padre al figlio (Copy On Write).
Se riesci ad organizzare i dati in maniera che siano esattamente in pagine di memoria separate (sotto Linux la dimensione di una pagina standard sono 4K), forse te la puoi cavare sfruttando questo meccanismo (a patto ripeto che le pagine non vegano "sporcate" con nuove scritture). Dopodiché bisognerebbe effettivamente vedere come si comporta Python con quella memoria, non so che controllo puoi avere da quel punto di vista. Chiaramente rimane un trick ad-hoc, in generale non puoi assumere questo comportamento su altri sistemi (anche se penso che ormai tutti i sistemi operativi moderni adottino tecniche di questo tipo). Ultima modifica di WarDuck : 18-01-2015 alle 13:38. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Il problema è che, col meccanismo del reference counting usato in CPython, le pagine verranno copiate inevitabilmente al primo accesso, che sia in lettura o scrittura è indifferente, degli oggetti condivisi.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
@oNaSsIs: m'è venuto in mente che potresti provare con PyPy, che non ha né GIL né reference counting, e in più ha un ottimo JIT per accelerare, e pure di molto, le prestazioni.
L'ho già usato diverse volte, alcune anche in produzione, e s'è comportato benissimo finora.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Leuven
Messaggi: 667
|
Non puoi caricare i dati in una Queue o in una Pipe condivisa?
https://docs.python.org/3.4/library/...rocessing.html Oppure leggere un pezzetto di file con ogni processo... http://www.tutorialspoint.com/python/file_seek.htm
__________________
L'elettronica digitale non esiste, è solo elettrotecnica con interruttori piccoli!
|
|
|
|
|
|
#13 | ||||
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Quote:
Quote:
Quote:
Quote:
|
||||
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
|
Credo proprio di sì. Tanto una copia dell'oggetto in Python è soltanto una reference.
Riguardo a PyPy, so che al momento supporta un sottoinsieme di NumPy, per cui potrebbe anche essere sufficiente per quel che ti serve. Altre possibili soluzioni: IronPython e Jython, che implementano Python per .NET e JVM rispettivamente, e che fanno uso di tutti i core perché internamente si occupano loro della protezione delle loro strutture dati e della sincronizzazione / condivisione.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro @LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys |
|
|
|
|
|
#15 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Grazie mille cdimauro per l'aiuto! Vi farò sapere se risolvo!
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:30.




















