Re: [Python] Migliorare le prestazioni usando i core?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Il 31/03/2013 23:58, Aplemaser ha scritto: Il giorno 31 marzo 2013 22:02, Manlio Perillo manlio.peri...@gmail.com mailto:manlio.peri...@gmail.com ha scritto: Ok. Allora andiamo con ordine. Che database usi? Quanto tempo impiega il tuo codice, e quanto tempo vorresti impiegasse? [...] Attualmente il tempo di importazione è di 4 ore o poco meno. Voglio ridurre il tempo, ma non so fino a quanto posso arrivare. Con ottimizzazioni molto aggressive (sia sul tuo codice che sulla configurazione del database) non è impossibile scendere sotto i 30 minuti. Tutto è nato perchè ho notato che 3 core su 4 dormono i sonni dei giusti mentre l'altro corse lavora come un pazzo e quindi vorrei impegnare la CPU per ridurre questi tempi. L'alto utilizzo della CPU è solo del tuo programma, o di tutto il sistema (quindi incluso eventualmente il database) ? Se usi un sistema UNIX, puoi utilizzare il comando time per ottenere valori precisi dei tempi impiegati. Di preciso posso dirti che se i bytes totali dei file CSV sono dell'ordine dei 10GB, puoi ottenere un incremento di prestazioni da 5 a 8 volte *solo* ottimizzando il codice. Lo dico per esperienza personale con un parser che deve leggere riga per riga un file di 60G, e che l'implementazione ottimizzata scritta in C richiede 8 minuti, mentre quella Python e quella in C non ottimizzato richiedono più di un ora (ma non so di preciso quanto, perchè non avevo voglia di aspettare). Se poi devi inserire grosse moli di dati nel database, l'ottimizzazione della configurazione del database può portare ad incrementi di prestazioni notevoli. PostgreSQL permette *molte* ottimizzazioni, dal semplice e safe comando COPY a ottimizzazioni più agressive (e pericolose per l'integrità dei dati in caso di crash). Le ottimizzazioni che puoi fare dipendono da come processi i dati, e da come usi il database. Per questo dicevo che devi spiegare in modo chiaro e completo cosa devi fare, altrimenti chi legge può solo darti consigli generici che magari hanno il solo risultato di fare aumentare la tua confusione. Supponi che ciascun file CSV contenga i dati da inserire in una sola tabella. Invece di processare ciascun file CSV in seguenza, puoi farlo in parallelo usando un processo separato. [...] Non è la base di partenza che ho, cioè non ho CSV tutti uguali da importare in processi separati, ma ho capito esattamente il tuo suggerimento. Io non ho detto che devi avere files tutti uguali. L'importante che per processare ed inviare al database i dati di un file CSV, tu non abbia bisogno dei dati presenti in altri file CSV. Ancora grazie mille delle risposte e dell'attenzione. Ciao Manlio -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAlFZj08ACgkQscQJ24LbaUSrGQCeNWQd1C4uwQCoKCVkgRndKDgn oLMAoI7rjrQfpGE4x4up9l6nEbYrTo35 =txpm -END PGP SIGNATURE- ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
On 2013-03-31 22:58, Aplemaser wrote: Attualmente il tempo di importazione è di 4 ore o poco meno. Voglio ridurre il tempo, ma non so fino a quanto posso arrivare. Tutto è nato perchè ho notato che 3 core su 4 dormono i sonni dei giusti mentre l'altro corse lavora come un pazzo e quindi vorrei impegnare la CPU per ridurre questi tempi. Hai ragione: facendo andare in parallelo i core sfrutteresti meglio la macchina, e il tuo problema non è I/O bound altrimenti non vedresti neanche quel singolo core maxxato. Come farlo non è gratis e non c'è una ricetta generica. Se il tuo input è su tanti file, lancia 4 processi in parallelo e fai lavorare ognuno su 1/4 dell'input. Se il file di input è uno solo puoi spezzare il processo in due parti: uno che legge l'input, lo spezza e ne manda i pezzi in una coda; altri 3-4 processi che leggono dalla coda in round-robin e fanno il loro lavoro sul pezzetto. Per questo tipo di lavori ZeroMQ è perfetto: ha poco overhead e le primitive giuste per questo tipo di coordinazione. Come detto non esistono ricette generiche, ma esistono dei pattern generici, e 0MQ rende abbastanza semplice implementarli. Tieni conto che, dopo l'elaborazione, passare i dati a MySQL come stai probabilmente facendo (con delle INSERT) non è il modo più efficiente. Su PostgreSQL usare COPY è almeno 20 volte più efficiente di INSERT per il bulk-load dei dati. Se MySQL è opzionale come dici, abbandonalo e usa postgres: psycopg offre supporto a COPY da Python http://initd.org/psycopg/docs/usage.html#copy. Se resti in MySQL penso tu possa usare LOAD DATA INFILE per velocizzare il caricamento, ma è un po' più articolato (devi salvare i dati in un file temporaneo o creare una pipe). -- Daniele Varrazzo - Develer S.r.l. http://www.develer.com ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
Il giorno 01 aprile 2013 15:44, Manlio Perillo manlio.peri...@gmail.comha scritto: Con ottimizzazioni molto aggressive (sia sul tuo codice che sulla configurazione del database) non è impossibile scendere sotto i 30 minuti. Wow addirittura. Mi fai coraggio. Le ottimizzazioni che puoi fare dipendono da come processi i dati, e da come usi il database. Per questo dicevo che devi spiegare in modo chiaro e completo cosa devi fare, altrimenti chi legge può solo darti consigli generici che magari hanno il solo risultato di fare aumentare la tua confusione. Ho capito bene, solo che spiegare tutto quanto ho fatto in svariate settimane di lavoro non è per nulla facile. ho provato a farlo in maniera più esaustiva possibile, ma senza voler tediarvi oltremisura. Io non ho detto che devi avere files tutti uguali. L'importante che per processare ed inviare al database i dati di un file CSV, tu non abbia bisogno dei dati presenti in altri file CSV. Certo, sono io che ho sintetizzato sbagliando. Mi hai dato davvero un mucchio di materiale sul quale riflettere, grazie. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
Il giorno 01 aprile 2013 16:54, Daniele Varrazzo p...@develer.com ha scritto: Hai ragione: facendo andare in parallelo i core sfrutteresti meglio la macchina, e il tuo problema non è I/O bound altrimenti non vedresti neanche quel singolo core maxxato. Esatto, è il mio punto di partenza questo. Come farlo non è gratis e non c'è una ricetta generica. Se il tuo input è su tanti file, lancia 4 processi in parallelo e fai lavorare ognuno su 1/4 dell'input. Se il file di input è uno solo puoi spezzare il processo in due parti: uno che legge l'input, lo spezza e ne manda i pezzi in una coda; altri 3-4 processi che leggono dalla coda in round-robin e fanno il loro lavoro sul pezzetto. Per questo tipo di lavori ZeroMQ è perfetto: ha poco overhead e le primitive giuste per questo tipo di coordinazione. Come detto non esistono ricette generiche, ma esistono dei pattern generici, e 0MQ rende abbastanza semplice implementarli. Non conosco quanto citi e quindi approfondirò sicuramente. Sono consapevole che nulla ti è regalato e che devi sporcarti le mani per ottenere i migliori risultati. Tieni conto che, dopo l'elaborazione, passare i dati a MySQL come stai probabilmente facendo (con delle INSERT) non è il modo più efficiente. Su PostgreSQL usare COPY è almeno 20 volte più efficiente di INSERT per il bulk-load dei dati. Se MySQL è opzionale come dici, abbandonalo e usa postgres: psycopg offre supporto a COPY da Python http://initd.org/psycopg/**docs/usage.html#copyhttp://initd.org/psycopg/docs/usage.html#copy. Se resti in MySQL penso tu possa usare LOAD DATA INFILE per velocizzare il caricamento, ma è un po' più articolato (devi salvare i dati in un file temporaneo o creare una pipe). Bene, come dicevo è opzionale l'utilizzo di MySQL e quindi analizzerò volentieri il passaggio a PostgreSQL, almeno un test lo farò sicuramente. Grazie per le risposte. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
Aplemaser wrote: Bene, come dicevo è opzionale l'utilizzo di MySQL La parola che cercavi è autolesionista. -- Nicola Larosa - http://www.tekNico.net/ My knowledge enables me to predict that if you choose a closed- source OS, you have dangerously underestimated the long-term harm to yourself from that choice. - Eric Raymond, July 2012 ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
On 04/01/2013 08:43 PM, Aplemaser wrote: Bene, come dicevo è opzionale l'utilizzo di MySQL e quindi analizzerò volentieri il passaggio a PostgreSQL, almeno un test lo farò sicuramente. Di solito MySQL e` parte del problema, non della soluzione (anche se prendendolo un po' a calci con scarpe antinfortunistica riesci a farlo andare come vuoi te) ;) Enrico ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
[Python] Migliorare le prestazioni usando i core?
Ciao a tutti e buona pasqua. Dopo aver sviluppato, con estrema soddisfazione, un applicativo che importa/trasforma/riscrive una notevole mole di dati (almeno per me) da uno o più file CSV ad un database SQL, ora sto affrontando la difficile opera di tuning, perché i tempi sono importanti dovendo interagire con oltre 20.000.000 di record tutti i santi giorni. Dallo studio delle prestazioni hardware della macchina che esegue l'operazione ho notato che solo uno dei 4 core presenti durante la lavorazione va a saturazione, mentre gli altri restano relativamente a riposo. Ammetto di essere un completo ignorante in materia e mi scuso se la domanda non è pertinente, ma dopo aver girovagato in rete (a dire il vero ho trovato molte informazioni datate, non so se più valide) mi è sembrato di capire che si potrebbero usare dei moduli precisi per far usare più core, come threading o processing. Prima di fare/dire bestialità ho pensato di chiedere consiglio a voi che magari avete già avuto esperienza similari, magari indicandomi delle risorse di esempio. L'obbiettivo è di eseguire più operazioni in parallelo anziché in una unica. Tanto per completare l'informazione la versione di Python utilizzata è la 2.7 su un sistema Debian 6.0.6. Ciao a tutti e grazie dell'attenzione. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Il 31/03/2013 20:18, Aplemaser ha scritto: Ciao a tutti e buona pasqua. Dopo aver sviluppato, con estrema soddisfazione, un applicativo che importa/trasforma/riscrive una notevole mole di dati (almeno per me) da uno o più file CSV ad un database SQL, Alcuni database come PostgreSQL sono in grado di leggere direttamente files in formato CSV, ovviamente aggiungendo un header opportuno. ora sto affrontando la difficile opera di tuning, perché i tempi sono importanti dovendo interagire con oltre 20.000.000 di record tutti i santi giorni. In linea di massima, e in particolare considerando come hai sviluppato il codice (ossia se passi molto tempo a manipolare stringhe, invece che a leggere/scrivere su file), una riscrittura in C dovrebbe risolvere il problema senza usare threads addizionali. Dallo studio delle prestazioni hardware della macchina che esegue l'operazione ho notato che solo uno dei 4 core presenti durante la lavorazione va a saturazione, mentre gli altri restano relativamente a riposo. Certo, perchè in qualsiasi linguaggio, a meno di non avere codice speciale, usi sempre e solo un unico thread. Ammetto di essere un completo ignorante in materia e mi scuso se la domanda non è pertinente, ma dopo aver girovagato in rete (a dire il vero ho trovato molte informazioni datate, non so se più valide) mi è sembrato di capire che si potrebbero usare dei moduli precisi per far usare più core, come threading o processing. Esatto. Quale usare dipende però da cosa fa il tuo codice. In generale se usi più processi è meglio, perchè in Python può girare solo un thread alla volta (cerca su Internet Python GIL). Prima di fare/dire bestialità ho pensato di chiedere consiglio a voi che magari avete già avuto esperienza similari, magari indicandomi delle risorse di esempio. L'obbiettivo è di eseguire più operazioni in parallelo anziché in una unica. Non esiste nessun comando magico che ti parallelizzi il codice. Tanto per completare l'informazione la versione di Python utilizzata è la 2.7 su un sistema Debian 6.0.6. Devi dirci esattamente cosa sta facendo il tuo codice. Meglio se il codice è breve e lo puoi mettere su pastebin o simili. In generale per parallelizzare del codice, lo devi partizionare in N pezzi indipendenti, ed eseguire ciascun pezzo in un thread. Di solito N = numero di core oppure N = n * numero di core, dipende da cosa fa il codice, in particolare dal tempo speso in I/O). Ciao Manlio -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAlFYgT0ACgkQscQJ24LbaUSsAwCfRFrwaWlauyXhmxFBXStBM7+d 50gAoIgRJlu/eARDifEKeSAPItFNQdy2 =B/ME -END PGP SIGNATURE- ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
Il giorno 31 marzo 2013 20:32, Manlio Perillo manlio.peri...@gmail.com ha scritto: Alcuni database come PostgreSQL sono in grado di leggere direttamente files in formato CSV, ovviamente aggiungendo un header opportuno. Sì lo so, ma non è il mio caso. In linea di massima, e in particolare considerando come hai sviluppato il codice (ossia se passi molto tempo a manipolare stringhe, invece che a leggere/scrivere su file), una riscrittura in C dovrebbe risolvere il problema senza usare threads addizionali. Non conosco i C se non per i rudimenti scolastici di parecchi anni fa. Certo, perchè in qualsiasi linguaggio, a meno di non avere codice speciale, usi sempre e solo un unico thread. Ok, Non esiste nessun comando magico che ti parallelizzi il codice. Ho capito dalla tua risposta di aver usato un termine improprio, cancella la mia richiesta, volevo usare un sinonimo della prima. Devi dirci esattamente cosa sta facendo il tuo codice. Meglio se il codice è breve e lo puoi mettere su pastebin o simili. Il codice è molto lungo e diviso in diversi file, copiarlo su pastebin non è davvero possibile. In linea di massima da fonti diverse che sono file CSV in prevalenza, ma anche alcune viste logiche (via ODBC), creo un solo database con tutti i dati, dopo averli mergiati e manipolati secondo necessità. In generale per parallelizzare del codice, lo devi partizionare in N pezzi indipendenti, ed eseguire ciascun pezzo in un thread. Di solito N = numero di core oppure N = n * numero di core, dipende da cosa fa il codice, in particolare dal tempo speso in I/O). Non mi è familiare, ma ho capito il senso. Grazie delle risposte. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Il 31/03/2013 21:49, Aplemaser ha scritto: [...] Il codice è molto lungo e diviso in diversi file, copiarlo su pastebin non è davvero possibile. In linea di massima da fonti diverse che sono file CSV in prevalenza, ma anche alcune viste logiche (via ODBC), creo un solo database con tutti i dati, dopo averli mergiati e manipolati secondo necessità. Ok. Allora andiamo con ordine. Che database usi? Quanto tempo impiega il tuo codice, e quanto tempo vorresti impiegasse? Ciascun file CSV e vista ODBC serve per inserire i dati in una tabella diversa? In generale per parallelizzare del codice, lo devi partizionare in N pezzi indipendenti, ed eseguire ciascun pezzo in un thread. Di solito N = numero di core oppure N = n * numero di core, dipende da cosa fa il codice, in particolare dal tempo speso in I/O). Non mi è familiare, ma ho capito il senso. Supponi che ciascun file CSV contenga i dati da inserire in una sola tabella. Invece di processare ciascun file CSV in seguenza, puoi farlo in parallelo usando un processo separato. Ciascun processo si occuperà di: - - aprire il file CSV - - aprire una connessione al database - - fare il parsing del file CSV - - inserire i dati nel database Dai una occhiata alla documentazione del modulo multiprocessing, disponibile da Python 2.6. Ciao Manlio -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAlFYll8ACgkQscQJ24LbaUQjwACeJjYTWnsFaNeUUW17llTAsXyf 5aYAn2E0yQ75wOpAZDp0KtL1/4gzeiug =jwtj -END PGP SIGNATURE- ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
Il giorno 31 marzo 2013 22:02, Manlio Perillo manlio.peri...@gmail.com ha scritto: Ok. Allora andiamo con ordine. Che database usi? Quanto tempo impiega il tuo codice, e quanto tempo vorresti impiegasse? Ciascun file CSV e vista ODBC serve per inserire i dati in una tabella diversa? I dati dei CSV e le viste ODBC servono, dopo opportune bonifiche (spazi superflui, caratteri speciali, valori numerici trasformati in valori testuali, etc), per compilare diverse tabelle diverse. Si tratta di anagrafiche di prodotti, che hanno logiche di gestione diverse, con disponibilità e prezzi variabili anche più volte al giorno. Questi dati vengono poi consultati su un database MySQL, ma qui non ho nessun vincolo, potrei usare anche altro. Le origini dei dati non sono fisicamente sulla macchina dove risiedono script in Python e database MySQL. Attualmente il tempo di importazione è di 4 ore o poco meno. Voglio ridurre il tempo, ma non so fino a quanto posso arrivare. Tutto è nato perchè ho notato che 3 core su 4 dormono i sonni dei giusti mentre l'altro corse lavora come un pazzo e quindi vorrei impegnare la CPU per ridurre questi tempi. Supponi che ciascun file CSV contenga i dati da inserire in una sola tabella. Invece di processare ciascun file CSV in seguenza, puoi farlo in parallelo usando un processo separato. Ciascun processo si occuperà di: - - aprire il file CSV - - aprire una connessione al database - - fare il parsing del file CSV - - inserire i dati nel database Dai una occhiata alla documentazione del modulo multiprocessing, disponibile da Python 2.6. Non è la base di partenza che ho, cioè non ho CSV tutti uguali da importare in processi separati, ma ho capito esattamente il tuo suggerimento. Ancora grazie mille delle risposte e dell'attenzione. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
2013/3/31 Aplemaser deevot...@gmail.com: Attualmente il tempo di importazione è di 4 ore o poco meno. Voglio ridurre il tempo, ma non so fino a quanto posso arrivare. Tutto è nato perchè ho notato che 3 core su 4 dormono i sonni dei giusti mentre l'altro corse lavora come un pazzo e quindi vorrei impegnare la CPU per ridurre questi tempi. La butto là: stai già usando le transazioni? Visto che parliamo di import su DB dubito la CPU sia un problema, la scrittura su disco è, di norma, sempre la parte più lenta. -- Gianluca Sforna http://morefedora.blogspot.com http://identi.ca/giallu - http://twitter.com/giallu ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
Il giorno 01 aprile 2013 00:48, Gianluca Sforna gia...@gmail.com ha scritto: La butto là: stai già usando le transazioni? Non le ho prese in considerazione, diciamo che grazie a voi sto raccogliendo materiale per le mie indagini. Visto che parliamo di import su DB dubito la CPU sia un problema, la scrittura su disco è, di norma, sempre la parte più lenta. Sull'utilizzo della CPU la mia è una considerazione del tutto empirica, visto che non è solo lettura e scrittura dei file, evidentemente non è solo utilizzo di disco. Il mio ragionamento è molto semplice e forse sbagliato nella mia ingenuità: se nelle 4 ore in cui eseguo l'operazione 1/4 dei core è al 99% di utilizzo, mentre gli altri 3/4 sono al 2-4%, se riesco a scomporre il processo in modo da utilizzare 3/4 al 99% posso sicuramente ottimizzare il tutto. Grazie anche a te per le risposte. ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
2013/4/1 Aplemaser deevot...@gmail.com: Sull'utilizzo della CPU la mia è una considerazione del tutto empirica, visto che non è solo lettura e scrittura dei file, evidentemente non è solo utilizzo di disco. Il mio ragionamento è molto semplice e forse sbagliato nella mia ingenuità: se nelle 4 ore in cui eseguo l'operazione 1/4 dei core è al 99% di utilizzo, mentre gli altri 3/4 sono al 2-4%, se riesco a scomporre il processo in modo da utilizzare 3/4 al 99% posso sicuramente ottimizzare il tutto. Ti manca un pezzo nel ragionamento: può succedere benissimo che nelle 4 ore il 99% del tempo lo passa a leggere e scrivere su disco e l'1% a far lavorare la CPU. Quindi il primo passo è lasciare perdere le supposizioni e dedicarti alla misura. Python ha diversi sistemi di profiling con cui puoi facilmente capire dove ti conviene lavorare. Tieni prensente che non c'è bisogno di farlo per tutte le 4 ore, ti basta un piccolo set. -- Gianluca Sforna http://morefedora.blogspot.com http://identi.ca/giallu - http://twitter.com/giallu ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python
Re: [Python] Migliorare le prestazioni usando i core?
Il giorno 01 aprile 2013 01:08, Gianluca Sforna gia...@gmail.com ha scritto: Ti manca un pezzo nel ragionamento: può succedere benissimo che nelle 4 ore il 99% del tempo lo passa a leggere e scrivere su disco e l'1% a far lavorare la CPU. Quindi il primo passo è lasciare perdere le supposizioni e dedicarti alla misura. Python ha diversi sistemi di profiling con cui puoi facilmente capire dove ti conviene lavorare. Tieni prensente che non c'è bisogno di farlo per tutte le 4 ore, ti basta un piccolo set. Utilizzo Nagios e le mie indagini (mi inizio a sentire Clouseau) sono partite da lì. L''accesso in scrittura sul disco e quello di utilizzo della CPU sono dati separati, se non ho preso un abbaglio clamoroso. Comunque ottima idea quella di fare profiling prestazionale del codice direttamente con Python, hai qualche suggerimento o vado di Google? ___ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python