Posso parallelizzare facilmente questo script?

0

Ho uno script che confronta in qualche modo ogni riga da file1 e file2 , e restituisce le righe se c'è una differenza. Voglio renderlo più veloce - adesso è in Python. Potrei usare i thread, ma mi piacerebbe sapere c'è un modo più semplice per migliorarlo?

Poiché ogni test è indipendente, potrebbe essere eseguito in parallelo - Devo solo assicurarmi che ogni riga da file1 venga confrontata con ogni riga da file2 .

EDIT: il collo di bottiglia finora è il processore (processo di confronto); l'utilizzo del disco non è così grande, ma il core con il programma è al 100%. Nota che i file sono "grandi" (ad esempio oltre 20 MB), quindi ho capito che ci vuole del tempo per elaborarli.

    
posta MatthewRock 07.07.2016 - 11:37
fonte

3 risposte

0

Sono riuscito a paralizzarlo usando GNU Parallel .

In primo luogo, ho dovuto apportare alcune modifiche allo script: dovevo assicurarmi che solo la parte "file" utilizzasse il tentativo di riavviare il puntatore del file (non è possibile cercare su pipe). Ho anche dovuto usare questo trucco per ottenere utf8 stdout / stdin:

reload(sys)
sys.stedefaultencoding('utf8')

Dopodiché, ero pronto per chiamare lo script:

parallel --pipepart -a file_to_stdin ./myscript.py --secondfile second_fle > result

(pipepart consente a -a di essere trattato come input che va a stdin, invece di passare le righe dal file come argomenti)

In questo modo, le modifiche allo script erano minime e la concorrenza è stata raggiunta.

    
risposta data 11.07.2016 - 09:44
fonte
1

Se vuoi ottenere una reale parallelizzazione della CPU come Mason ha dichiarato che devi andare in giro GIL forking invece di usare thread. Questo ha un overhead extra rispetto ai thread ma potrebbe funzionare se il tempo di processo è il collo di bottiglia.

Il modo migliore per ottenere questo risultato in modo non hacky è utilizzare multiprocess.Pool e utilizzare una variante di map . Ciò invierà il tuo iterable a un pool di lavoratori che utilizzeranno l'input e aggregeranno il risultato nel processo principale.

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
         print(p.map(f, [1, 2, 3])) #[1, 4, 9]
    
risposta data 07.07.2016 - 16:02
fonte
0

Probabilmente no.

Python ha un cosiddetto Global Interpreter Lock che garantisce che l'interprete non venga mai eseguito su più thread di un processo alla volta. Ciò significa che, a meno che l'elaborazione non stia facendo uso molto pesante dell'elaborazione del codice nativo come NumPy che trascorre la maggior parte del tempo fuori dall'interprete, è impossibile accelerarlo parallelizzandolo .

Potresti ottenere alcuni guadagni di velocità parallelizzando il multiprocessing , ma ciò può imporre un pesante sovraccarico per l'installazione e la comunicazione, quindi è difficile dirlo con certezza senza testarlo.

    
risposta data 07.07.2016 - 11:54
fonte

Leggi altre domande sui tag