0

計算を。で並列化しようとしていますrpc:pmap。しかし、私はそのパフォーマンスと少し混乱しています。

簡単な例を次に示します。

-module(my_module).
-compile(export_all).

    do_apply( X, F ) -> F( X ).

まず第一に-単一ノードでテストします:

1> timer:tc( rpc, pmap, [{my_module, do_apply}, [fun(X) -> timer:sleep(10), X end], lists:seq(1,10000)] ).
{208198,
 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
  23,24,25,26,27|...]}

その後、2番目のノード(OSの2番目のerlangシェルプロセス)に接続しました:

(foo@Stemm.local)24> timer:tc( rpc, pmap, [{my_module, do_apply}, [fun(X) -> timer:sleep(10), X end], lists:seq(1,10000)] ).
{446284,
 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
  23,24,25,26,27|...]}

最後に、3番目のノードを接続しました。

(foo@Stemm.local)26> timer:tc( rpc, pmap, [{my_module, do_apply}, [fun(X) -> timer:sleep(10), X end], lists:seq(1,10000)] ).
{483399,
 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
  23,24,25,26,27|...]}

つまり、3つのノードでは1つのノードよりもパフォーマンスが低下します。

ノード間の通信にはいくらかのオーバーヘッドがあることに気づきました。しかし、どの場合に複数のノードで計算を実行する方がよいかをどのように理解できますか?

編集:

シェルからの私の段階的なテスト:

1> c(my_module).
{ok,my_module}
2>  
2> List = lists:seq(1,10000).
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
 23,24,25,26,27,28,29|...]

単一ノードでのパフォーマンスのテスト:

3> timer:tc( rpc, pmap, [{my_module, do_apply}, [fun(X)-> timer:sleep(10), X end], List] ).
{207346,
 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
  23,24,25,26,27|...]}

ネットワーク環境への入り口:

4> net_kernel:start([one]).
{ok,<0.20066.0>}
(one@Stemm.local)5> erlang:set_cookie(node(), foobar).
true

2番目のノードを追加します。

(one@Stemm.local)6> net_kernel:connect('two@Stemm.local').
true
(one@Stemm.local)7> 
(one@Stemm.local)7> nodes().
['two@Stemm.local']

2つのノードでパフォーマンスをテストします。

(one@Stemm.local)8> timer:tc( rpc, pmap, [{my_module, do_apply}, [fun(X)-> timer:sleep(10), X end], List] ).
{510733,
 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
  23,24,25,26,27|...]}

3番目のノードを接続します。

(one@Stemm.local)9> net_kernel:connect('three@Stemm.local').
true
(one@Stemm.local)10> nodes().
['two@Stemm.local',
 'three@Stemm.local']

3つのノードでパフォーマンスをテストします。

(one@Stemm.local)11> timer:tc( rpc, pmap, [{my_module, do_apply}, [fun(X)-> timer:sleep(10), X end], List] ).
{496278,
 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
  23,24,25,26,27|...]}

PS同じ物理マシンで新しいerlang-shellプロセスとして各ノードを作成しているため、パフォーマンスが低下すると思います。しかし、私が正しいかどうかは正確にはわかりません。

4

1 に答える 1

3

Erlangで並列処理を行うためにノードを追加する必要はありません。各ノードは、ローカルで多数のプロセスをサポートできます。 pmapはすでに関数を並行して実行しています。これは、待機時間を長くすると見やすくなります。

timer:tc( rpc, pmap, [{my_module, do_apply}, [fun(X) -> timer:sleep(1000), X end], lists:seq(1,10000)] ).
{1158174,
 [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
  23,24,25,26,27|...]}

1000 * 10000 = 10,000,000スリープが1つのノードで連続して実行されている場合、最小待機時間は、と予想され、待機するだけで済みます。1,158,174

3つの別々のErlangVMを作成し、それらを相互に接続しています。次に、それらのVMの1つで並列マップを実行しています。追加のVMは、すべて同じ物理リソースを使用しようとしているため、現在のセットアップでパフォーマンスを低下させるだけであり、そのうちの2つは作業を実行していません。

複数のノードは、異なる物理リソースで実行されている場合にのみパフォーマンスを向上させます。

于 2012-09-13T23:32:44.957 に答える