2

perl モジュールの一部として完全に優れた perl サブルーチンを作成しました。あまり詳細には触れずに、文字列と短いリストを引数として (端末から取得することが多い) 取り、値を吐き出します (現在、常に浮動小数点ですが、常にそうであるとは限りません)。

現在、引数のリスト部分は 2 つの値、たとえば (val1,val2) を取ります。for ループを使用して、val1 と val2 の何百もの異なる値のサブルーチンの出力を保存します。各反復が完了するまでにほぼ 1 秒かかるため、このプロセス全体を完了するには数時間かかります。

私は最近、「スレッド化」と呼ばれる神秘的な (私にとって) 計算ツールについて読みました。これは明らかに for ループを非常に高速な実行時間に置き換えることができます。これらが何なのか、何をするのか理解に苦しんでいますが、並列コンピューティングと関係があるのではないかと思います (また、並列プロセッサ用にモジュールを可能な限り最適化したいと考えています)。

val1 に渡したいすべての値をリストとして保存する場合、たとえば @val1 と val2 についても同様にすると、これらの「スレッド」を使用して、val1 と val2 の要素のすべての組み合わせに対してサブルーチンを実行するにはどうすればよいでしょうか? また、この手順を val3、val4 なども受け取るサブルーチンに一般化する方法を知っておくと役立ちます。

4

1 に答える 1

6

アップデート:

私は PDL を使用していないので、PDL のスレッドが、私が話してきたスレッド化の概念に正確に対応していないことを知りませんでした。PDL のスレッド化と署名を参照してください。

最初に、PDL のコンテキストでスレッド化が何を意味するのかを説明する必要があります。特に、スレッド化という用語は、コンピューター サイエンスでは既に明確な意味を持ち、PDL 内での使用法とは部分的にしか一致しないためです。

ただし、PDL スレッドがどのように異なるかを理解するには、通常の意味でのスレッド化とは何かを知る必要があるため、以下の説明は依然として役立つと思います。

背景については、Wikipedia の Threads エントリを参照してください。

スレッドを使用しても、プログラムを魔法のように高速化することはできません。複数の CPU/コアがあり実行している計算を独立したチャンクに分割できる場合、スレッドを使用すると、プログラムで一度に複数の計算を実行し、合計実行時間を短縮できます

最も簡単なケースは、サブタスクが途方もなく並列で、スレッド間の通信/調整を必要としない場合です。

可能なパフォーマンスの向上については、次のプログラムを検討してください。

#!/usr/bin/perl

use strict; use warnings;
use threads;

my ($n) = @ARGV;

my @threads = map { threads->create(\&act_busy) } 1 .. $n;

$_->join for @threads;

sub act_busy {
    for (1 .. 10_000_000) {
        my $x = 2 * 2;
    }
}

Windows XP を実行しているデュアル コア ラップトップの場合:

C:\> timethis t.pl 1
TimeThis : 経過時間 : 00:00:02.375
C:\> timethis t.pl 2
TimeThis : 経過時間 : 00:00:02.515
C:\> timethis t.pl 3
TimeThis : 経過時間 : 00:00:03.734
C:\> timethis t.pl 4
TimeThis : 経過時間 : 00:00:04.703
...
C:\> timethis t.pl 10
TimeThis : 経過時間 : 00:00:11.703

今、それを比較してください:

#!/usr/bin/perl

use strict; use warnings;

my ($n) = @ARGV;

act_busy() for 1 .. $n;

sub act_busy {
    for (1 .. 10_000_000) {
        my $x = 2 * 2;
    }
}
C:\> timethis s.pl 10
TimeThis : 経過時間 : 00:00:22.312
于 2010-09-08T00:15:28.660 に答える