11

処理する必要のあるさまざまなディレクトリに約500GBの画像があります。各画像のサイズは約4MBで、各画像を一度に1つずつ処理するPythonスクリプトがあります(メタデータを読み取り、データベースに保存します)。サイズによっては、各ディレクトリの処理に1〜4時間かかる場合があります。

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

もう1つのオプションは、GearmanやBeanstalkなどを使用して、作業を他のマシンにファームアウトすることです。マルチプロセッシングライブラリを調べましたが、どのように利用できるかわかりません。

4

6 に答える 6

6

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

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

もう 1 つのオプションは、Gearman や Beanstalk などを使用して、他のマシンに作業を委託することです。

それはうまくいくかもしれません。また、ZeroMQ の Python バインディングを見てください。これにより、分散処理が非常に簡単になります。

multiprocessing ライブラリを調べましたが、それをどのように利用できるかわかりません。

processたとえば、単一のディレクトリ内の画像を読み取り、データベースに接続してメタデータを保存する関数を定義します。成功または失敗を示すブール値を返すようにします。処理するディレクトリdirectoriesのリストとします。それで

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

すべてのディレクトリを並行して処理します。必要に応じて、ファイルレベルで並列処理を行うこともできます。もう少しいじる必要があります。

これは最初の失敗で停​​止することに注意してください。耐障害性を持たせるには、もう少し手間がかかります。

于 2012-04-04T14:17:30.107 に答える
4

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

実験して、インスタンスの理想的な数を確認することをお勧めします。これは、コアの数より多い場合も少ない場合もあります。ディスクとキャッシュ メモリの競合が発生しますが、一方で、I/O を待機している別のプロセスが実行されている可能性があります。

于 2012-04-04T14:18:53.160 に答える
4

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

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倍くらい速くなります。ワーカー数をコアの 2 倍、またはコア数と同じに設定することをお勧めします。試してみて、どの構成がより高速かを確認できます。

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

ここに画像の説明を入力

これが役立つことを願っています。

于 2012-04-04T14:51:00.917 に答える
2

この質問への回答を参照してください。

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

その質問は Windows 固有のように見えますが、すべてのオペレーティング システムのシングル スレッド プログラムに当てはまります。

警告:このプロセスは I/O バウンドであり、ハード ドライブへの同時アクセスが多すぎると、I/O リソースの競合により、グループとしてのプロセスの実行が順次処理よりも遅くなることに注意してください。

于 2012-04-04T14:21:58.590 に答える
0

多数のファイルを読み取り、メタデータをデータベースに保存する場合、プログラムにそれ以上のコアは必要ありません。

プロセスは、CPU バウンドではなく IO バウンドである可能性があります。適切な defered と callback で twisted を使用すると、4 つのコアを使用しようとするソリューションよりも優れたパフォーマンスを発揮する可能性があります。

于 2012-04-04T15:13:45.897 に答える
0

このシナリオでは、 Celeryを使用することは完全に理にかなっていると思います。

于 2015-01-22T12:24:31.097 に答える