论坛首页 综合技术论坛

对Erlang使用SMP模式效率更低的猜想

浏览 4681 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-04-08  
在erlang maillist 看到有人发了个邮件: Process spawn time with -smp

引用
erl -noshell +P 1000000 -s processes max 800000 -s init stop
Maximum allowed processes:1000000
Process spawn time=4.16250 (8.02000) microseconds

erl -smp -noshell +P 1000000 -s processes max 800000 -s init stop
Maximum allowed processes:1000000
Process spawn time=19.7000 (28.0012) microseconds


max(N) ->
  Max = erlang:system_info(process_limit),
  io:format("Maximum allowed processes:~p~n" ,[Max]),
  statistics(runtime),
  statistics(wall_clock),
  L = for(1, N, fun() -> spawn(fun() -> wait() end) end),
 {_, Time1} = statistics(runtime),
 {_, Time2} = statistics(wall_clock),
 lists:foreach(fun(Pid) -> Pid ! die end, L),
 U1 = Time1 * 1000 / N,
 U2 = Time2 * 1000 / N,
 io:format("Process spawn time=~p (~p) microseconds" ,
 [U1, U2]).

wait() ->
 receive
  die -> void
 end.
 for(N, N, F) -> [F()];
 for(I, N, F) -> [F()|for(I+1, N, F)].



之前,我曾在一四核服务器上运行过一程序,

引用
-module(message).
-export([main/1, loop/1]).

main(Times) when is_integer(Times) ->
    Last = start(500, self()),
    io:fwrite("~p~n", [sendtimes(Times, Last, 0)]);
main([Arg]) ->
    N = list_to_integer(Arg),
    Last = start(500, self()),
    io:fwrite("~p~n", [sendtimes(N, Last, 0)]),
    erlang:halt(0).

start(0, LastPID) -> LastPID;

start(X, LastPID) -> start(X-1, spawn(message, loop, [LastPID])).

loop(LastPID) ->
receive
N ->
LastPID ! N+1,
loop(LastPID)
end.

sendtimes(0,_ ,X) -> X;

sendtimes(N, Last, X) ->
Last ! 0,
receive Y -> Y end,
sendtimes(N-1, Last, X+Y).


这是一个消息传递链的例子,本以为在多核上会更快一些,但是使用了 -smp 之后,反而更加慢。

按照我的猜测,这是由于Erlang Scheduler所产生的开销大于Process代码运行的开销造成的。Erlang VM相比Python、Ruby这些VM,优势在于Process(Thread)能够调度于不同的Core上执行,但是这个调度是有开销的。上面的程序都有一个特点,Process要做的事情很少,但是数量多,被分配到不同的Core中执行。在T1的《一场茶杯里的风暴》一文有如下文字:

引用
对待multi-processor的情况Erlang通常的策略是,为每一个CPU分配一个工作线程.在不同的native thread中的processor进行Message Passing 就不是一个原子操作了.在这个问题上Erlang通过一个非常巧妙的方法来保证Message Passing的同步.
当一个Sender Process 要准备向Reciver Process发送一个Message的时候,Scheduler首先会检查这两个Process是不是在一个native thread中,如果是则按常规方法进行Message Passing,如果不是Scheduler会把reciver从一个native thread调度到Sender 所在的native thread里,当recive结束后根据调度策略决定是否再将reciver调度回原来的native thread中. 这样就保证了多CPU上的Message passing仍然是原子的.


可见,这里以及涉及到了一个检查操作和Native Thread的切换,这个开销相比Process执行代码的开销是很大的,这抵消了多核并发执行的好处。因此使用smp比单纯在一个core里面执行更慢。
   发表时间:2007-04-09  
目前Windows 版本的Erlang,还不支持SMP.

Process要做的事情很少,但是数量多
对于这种应用,SMP本身不会带来大量的性能提升.
因为无论是Message Passing,还是Lock都是一种同步策略.两个并发实体如果只是互相等待同步,实则上是一种串行代码,如果不考虑IO并发,单Thread/Process的性能肯定要比并发/并行的版本高.


0 请登录后投票
   发表时间:2007-08-16  
small message, big computation SMP才有意义
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics