2012-04-04 23 views
11

処理する必要があるさまざまなディレクトリに約500GBの画像があります。各画像のサイズは約4MBで、一度に1画像ずつ処理するpythonスクリプトがあります(メタデータを読み込んでデータベースに保存します)。各ディレクトリは、サイズに応じて処理するのに1〜4時間かかります。Pythonで大きなファイルを処理する最速の方法

GNU/Linux OSでは、2.2Ghzクアッドコアプロセッサと16GBのRAMが用意されています。現在のスクリプトは1つのプロセッサしか使用していません。他のコアとRAMを活用して画像を高速に処理する最良の方法は何ですか?スクリプトを実行するために複数のPythonプロセスを開始すると、他のコアを利用できますか?

もう1つの方法は、GearmanやBeanstalkのようなものを使用して、他のマシンに作業を送り出すことです。私はマルチプロセッシングライブラリを見てきましたが、どのように活用できるかはわかりません。

+0

[Windows 7のすべてのコアの使い方は?](http://stackoverflow.com/questions/3055696/how-to-use-all-the-cores-in-windows-7) –

+1

必要なファイル/ディレクトリを指すことができる作業スクリプトが既にある場合は、必要なだけ多くのインスタンスを起動するシェルスクリプトを作成することを検討してください。 –

+4

私はボトルの首がどこにあるのか見ることから始めたいと思います。あなたがIOを実行するあなたの時間の大部分を費やしているなら、はるかに速く行くことはできません。たとえば、あるプロセスが特定の速度でディスクからデータをロードすると、複数のプロセスがディスクを噛み込んでいるときにその速度を維持することはほとんどありません。 –

答えて

6

スクリプトを実行するために複数のPythonプロセスを開始すると、他のコアを利用できますか?

はい、タスクがCPUにバインドされているとします。これはおそらく最も簡単なオプションです。ただし、ファイルごとまたはディレクトリごとに1つのプロセスを生成しないでください。 parallel(1)などのツールを使用し、コアごとに2つのプロセスのようなものを生成させることを検討してください。

もう1つの選択肢は、GearmanやBeanstalkのようなものを使用して、他のマシンに作業を送り出すことです。

これはうまくいく可能性があります。また、Python binding for ZeroMQを見ると、分散処理が非常に簡単になります。

私はマルチプロセッシングライブラリを見ましたが、どのように活用できるかはわかりません。

1つのディレクトリで画像を読み取り、メタデータを格納する関数、たとえばprocessを定義します。成功か失敗かを示すbooleanを返します。処理するディレクトリのリストをdirectoriesとします。その後、

import multiprocessing 
pool = multiprocessing.Pool(multiprocessing.cpu_count()) 
success = all(pool.imap_unordered(process, directories)) 

は、すべてのディレクトリを並行して処理します。また、必要に応じてファイルレベルで並列処理を行うこともできます。それはちょっとだけ手を加える必要があります。

これは最初の失敗時に停止することに注意してください。フォールトトレラントにするにはもう少し作業が必要です。

4

独立したPythonプロセスを開始することが理想的です。プロセス間でロックの競合はなく、OSは同時に実行するようにスケジュールします。

理想的なインスタンスの数が何であるかを確認するために実験したいかもしれません。コアの数よりも多くても少なくてもかまいません。ディスクとキャッシュメモリには競合がありますが、一方ではI/Oを待っている間に1つのプロセスを実行することがあります。

2

answerからquestionを参照してください。

アプリは、入力データの範囲を処理できる場合は、 を処理するために、入力データの異なる範囲でのアプリの4つの インスタンスを起動することができ、それらがすべて完了した後に結果を組み合わせます。

この質問はWindows固有のものですが、すべてのオペレーティングシステムのシングルスレッドプログラムに適用されます。

WARNING:このプロセスは、I/Oバウンドし、ハードドライブにあまりにも多くの同時アクセスになることに注意が実際にいるので、私の競合の逐次処理よりも遅くを実行するために、グループとしてのプロセスが発生します/ Oリソース。

4

マルチプロセッシングプールを使用して、パフォーマンスを向上させるプロセスを作成できます。たとえば、画像を処理する関数handle_fileがあります。反復を使用する場合は、コアの最大100%しか使用できません。複数のコアを利用するために、プールマルチプロセッシングはサブプロセスを作成し、タスクをそれらに配布します。次に例を示します。

import os 
import multiprocessing 

def handle_file(path): 
    print 'Do something to handle file ...', path 

def run_multiprocess(): 
    tasks = [] 

    for filename in os.listdir('.'): 
     tasks.append(filename) 
     print 'Create task', filename 

    pool = multiprocessing.Pool(8) 
    result = all(list(pool.imap_unordered(handle_file, tasks))) 
    print 'Finished, result=', result 

def run_one_process(): 
    for filename in os.listdir('.'): 
     handle_file(filename) 

if __name__ == '__main__': 
    run_one_process 
    run_multiprocess() 

run_one_processは、データを処理するための単純な方法ですが、遅いです。一方、run_multiprocessは8つのワーカープロセスを作成し、それらにタスクを配布します。 8つのコアを持っていると、約8倍速くなります。私はあなたのコアの倍数またはあなたのコアの数にワーカー番号を設定することをお勧めします。あなたはそれを試してどの構成がより速いかを見ることができます。

先進的な分散コンピューティングの場合、上記のlarsmansとしてZeroMQを使用できます。最初は分かりにくいです。しかし、理解すれば、データを処理するための非常に効率的な分散システムを設計することができます。あなたのケースでは、複数のREPを持つ1つのREQで十分だと思います。

enter image description here

が、これは参考になると思います。

0

多くのファイルを読み込んでおり、メタデータをデータベースに保存している場合、プログラムするにはより多くのコアが必要ありません。

あなたのプロセスはIOバウンドでCPUに束縛されていない可能性があります。適切なデフェーズとコールバックでねじれを使用すると、4つのコアを獲得しようとしていたソリューションよりも優れている可能性があります。

0

このシナリオでは、Celeryを使用すると完全に意味があると思います。

関連する問題