PERLスクリプトを変更して複数のプロセッサを使用するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/4429544

質問

こんにちは、ファイルを取得し、その上に別のPerlスクリプトを実行する簡単なスクリプトがあります。スクリプトは、現在のフォルダー内のすべての画像ファイルにこれを行います。これは、2つのQuad Core Xeonプロセッサ、16GBのRAMを備えたマシンで実行されており、Redhat Linuxを実行しています。

最初のスクリプトwork.plは基本的にMagicPlate.plを呼び出します。いくつかのパラメーターとMagicPlate.plのファイルの名前を処理します。マジックプレートは、各画像を処理するのに約1分かかります。 work.plは同じ関数を100回以上プレフォームしているため、システムには複数のプロセッサとコアがあるため、タスクを複数回並列に実行できるように考えていました。必要に応じて、画像をさまざまなフォルダーに分割できます。どんな助けも素晴らしいでしょう。ありがとうございました

これが私がこれまでに持っているものです:

use strict;
use warnings;


my @initialImages = <*>;

foreach my $file (@initialImages) {

    if($file =~ /.png/){
        print "processing $file...\n";
        my @tmp=split(/\./,$file);
        my $name="";
        for(my $i=0;$i<(@tmp-1);$i++) {
            if($name eq "") { $name = $tmp[$i]; } else { $name=$name.".".$tmp[$i];}
        }

        my $exten=$tmp[(@tmp-1)];
        my $orig=$name.".".$exten;

        system("perl magicPlate.pl -i ".$orig." -min 4 -max 160 -d 1");
     }
}       
役に立ちましたか?

解決

Parallel :: forkmanagerを使用できます($ max_processesを同時に処理したファイルの数に設定):

use Parallel::ForkManager;
use strict;
use warnings;

my @initialImages = <*>;

foreach my $file (@initialImages) {

    if($file =~ /.png/){
        print "processing $file...\n";
        my @tmp=split(/\./,$file);
        my $name="";
        for(my $i=0;$i<(@tmp-1);$i++) {
            if($name eq "") { $name = $tmp[$i]; } else { $name=$name.".".$tmp[$i];}
        }

        my $exten=$tmp[(@tmp-1)];
        my $orig=$name.".".$exten;

  $pm = new Parallel::ForkManager($MAX_PROCESSES);
    my $pid = $pm->start and next;
        system("perl magicPlate.pl -i ".$orig." -min 4 -max 160 -d 1");
    $pm->finish; # Terminates the child process

     }
}       

しかし、Hugmeirが新しいファイルごとに何度も何度も何度も実行しているHugmeirが示唆しているように、良い考えではありません。

他のヒント

処理したいファイルごとに新しいプロセスを作成しないことを検討する必要があります。それは恐ろしく非効率的であり、おそらくここでほとんどの時間を費やしているものです。 Perlと何度も使用するモジュールを何度もロードするだけで、オーバーヘッドを作成する必要があります。私は、似たようなことをして、彼の2番目のスクリプトをモジュールに変換し、ワークタイムを1時間から数回まで減らすことになったPerlmonksのポスターを思い出します . 。このような劇的な改善を期待するべきではありませんが、夢を見ることができます。

2番目のスクリプトがモジュールとしてリファクタリングされた場合、 スレッドの使用例は次のとおりです, 、browserukがスレッドプールを作成し、キューを通してジョブを供給します。

  • 「maigcplate」をインポートし、スレッドを使用します。
  • MagicPlate.plをバックグラウンドで開始します(プロセススロットリングを追加する必要があります)
  • 「MagicPlate」をインポートし、フォークを使用します(プロセススロットルとキディリーパーを追加)
  • 「maigcplate」を作業者のプールでデーモンにする=#of cpus
    • 通信にMQ実装を使用します
    • 通信にソケットを使用します
  • WebServer(nginx、apache、...)を使用し、Webサービスのために休憩して包みます
  • 等...

これらすべてが、それぞれが自分のCPUで走ることができる複数の労働者を作成することを中心にしています。特定の実装は、リソースをより適切に使用し(新しいプロセスを開始しないもの)、実装と保守が容易になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top