【问题标题】:Erlang rpc:pmap on multiple nodes vs. single nodeErlang rpc:pmap 在多个节点上与单个节点
【发布时间】:2012-09-14 07:32:44
【问题描述】:

我正在尝试将我的计算与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|...]}

之后我连接了第二个节点(我的操作系统中的第二个 erlang shell 进程):

(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|...]}

我终于连接了第三个节点:

(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|...]}

所以 - 我的 三节点性能比单节点性能更差

我意识到节点之间的通信存在一些开销。但是我怎么知道在哪些情况下在多个节点上执行计算更好呢?

编辑:

我在 shell 中的逐步测试:

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

添加第二个节点:

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

用两个节点测试性能:

(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|...]}

连接第三个节点:

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

用三个节点测试性能:

(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|...]}

P.S. 我猜性能会下降,因为我在同一台物理机器中将每个节点创建为一个新的 erlang-shell 进程。但我不知道我是否正确。

【问题讨论】:

  • 能否在调用 timer:tc 之前尝试生成列表?例如seq=lists:seq(1,10000), timer:tc(..., Seq)。
  • @Isac 是的,我试过了,但得到了类似的结果。我已经用 shell 中的分步测试描述编辑了我的问题。

标签: performance parallel-processing erlang pmap


【解决方案1】:

您无需添加节点即可在 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,158,174

您正在创建 3 个独立的 Erlang VM,并将它们相互连接。然后,您在其中一个虚拟机上运行并行映射。额外的虚拟机只会损害您当前设置的性能,因为它们都在尝试使用相同的物理资源,其中 2 个甚至没有运行任何工作。

只有在不同的物理资源上运行多个节点才能提高性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 2012-03-12
    • 2018-05-25
    • 1970-01-01
    相关资源
    最近更新 更多