erlang多进程间通信的性能测试

本文通过创建多个Erlang进程并发发送消息的方式,测试了进程间通讯的性能。结果显示,在进程数量较少时性能良好,但超过一定数量后性能下降显著。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

综述

上一篇是测试单个进程自己给自己发消息的速度, 差不多是每消息 1us。

如果编写实际的erlang程序,一定是一堆进程,进程之间相互发消息,为验证这种情况下消息收发的性能,写了个测试程序,程序的思路是:

       1)创建N个进程

       2)这N个进程,每个进程都再创建出一个接收进程,然后往那个进程发包,发M个包后,再给那个进程发个终止消息,给主进程发给自杀消息,然后自己终止

      3)接收进程仅负责收包,收到终止消息时退出,收到其他消息时继续

      4)主进程在创建了N个进程后,开始收消息,当收到N个进程的自杀消息后,大约统计时间并退出

 

测试结果

接下来的测试,M 我都设定为一百万,进程数和时间关键如下:

在1~100之间,性能下降低于线性,非常好;  到500个进程的时候,性能下降大大超过了线性。

进程数 总CPU耗时(ms)总流逝时间(ms)总CPU耗时增长总流水时间增长
1

0000910

904

  
10

0025680

6753

28倍7.5倍
100

0163900

41556

6.4倍6.2倍
50012905603260167.9倍7.8倍
1000

2602360

7009282倍2.1倍

 

 

从操作系统看, 运行过程中,CPU的 user部分可以占到 98%, erl进程的CPU使用率可到 399% (是虚拟机,就4个core)。

 

以下是测试过程中对  top 显示结果的随机截取,顺序是按时间顺序排列的。

可以看出erl的内存占用,是变大,然后变小,然后变大,但后期基本上变化幅度不大,都在300M左右。

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                           
 2213 erlang    21   0  344m 178m 2484 S 398.9  1.1   2:09.09 beam.smp   
 
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                           
 2213 erlang    21   0  379m 219m 2472 S 399.3  1.4   6:56.68 beam.smp
 
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                           
 2213 erlang    21   0  475m 313m 2424 S 319.3  2.0  10:23.55 beam.smp  
 
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                           
 2213 erlang    21   0  460m 305m 2424 S 264.6  1.9  11:18.18 beam.smp    
 
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                           
 2213 erlang    21   0  456m 303m 2424 S 398.9  1.9  20:37.05 beam.smp
 
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                           
 2213 erlang    21   0  162m  17m 2428 S  0.0  0.1  43:42.80 beam.smp            这是测试运行完一段时间后 

 

从打印结果看,非常有序,不像操作系统的线程输出,一片混乱,证实了erlang进程调度是完全平均分配的官方说法,1000个进程的测试中,不按下面次序打印的就五六个进程左右。

sendmsgs begin msg=1000000,Peer=<0.2032.0>.
sendmsgs begin msg=1000000,Peer=<0.2033.0>.
sendmsgs end msg=1000000,Peer=<0.710.0>.
sendor die PPID=<0.32.0>, pid=<0.211.0>,msgnum=1000000.
recvor dir <0.710.0>.
I=0,N=1000.
sendmsgs end msg=1000000,Peer=<0.647.0>.
sendor die PPID=<0.32.0>, pid=<0.148.0>,msgnum=1000000.
recvor dir <0.647.0>.
I=1,N=1000.
sendmsgs end msg=1000000,Peer=<0.1829.0>.
sendor die PPID=<0.32.0>, pid=<0.1311.0>,msgnum=1000000.
recvor dir <0.1829.0>.
I=2,N=1000.
sendmsgs end msg=1000000,Peer=<0.1543.0>.
sendor die PPID=<0.32.0>, pid=<0.1034.0>,msgnum=1000000.
I=3,N=1000.
recvor dir <0.1543.0>.
sendmsgs end msg=1000000,Peer=<0.939.0>.
sendor die PPID=<0.32.0>, pid=<0.440.0>,msgnum=1000000.
recvor dir <0.939.0>.
I=4,N=1000.
sendmsgs end msg=1000000,Peer=<0.834.0>.
sendor die PPID=<0.32.0>, pid=<0.335.0>,msgnum=1000000.
recvor dir <0.834.0>.

测试环境 

在租用的电信云主机上测试的。4cpu, 红帽的系统。

这批的云主机,使用的是华为的云平台,华为实际使用的是XEN虚拟化软件。

之后有在我们自己购买的PC Server上测试,安装了vmware云平台后再安装红帽系统,同样划出4个core(两个测试环境都没有打开超线程),

测试结果是:

华为云主机(XEN) TotalTime=174080(44086),

Vmware云主机           TotalTime=115240(29063)

Vmware云主机这性能的提升有 25% 啊,物理CPU还差一点,是E5  2GHz,难道是因为XEN太差了?

 

华为云主机的信息:

# uname -r
2.6.18-164.el5

# cat /proc/cpuinfo

processor       : 3
vendor_id       : GenuineIntel
cpu family      : 6
model           : 47
model name      :        Intel(R) Xeon(R) CPU E7- 4830  @ 2.13GHz
stepping        : 2
cpu MHz         : 2128.088
cache size      : 24576 KB
physical id     : 0
siblings        : 4
core id         : 3
cpu cores       : 4
apicid          : 6
fpu             : yes
fpu_exception   : yes
cpuid level     : 11
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc pni cx16 popcnt lahf_lm
bogomips        : 4255.64
clflush size    : 64
cache_alignment : 64
address sizes   : 44 bits physical, 48 bits virtual

 

代码

使用范例如下(输入参数表示 启动1000对进程, 每对进程发送1百万个报文): 
     yqmsg2:start(1000,1000000).
 
%%% yqmsg2.erl
-module(yqmsg2).
-export([start/2,mainwait/2,sendor/2]).

start(Thrs, Msgs) ->
    io:format("PID=~p,Max Message: ~p~n", [self(),Msgs]),
    statistics(runtime),
    statistics(wall_clock),
    PPID=self(),
    L = for(1, Thrs, fun()-> spawn(fun()-> sendor(PPID,Msgs) end) end),
    io:format("mainwait begin ~p ~n",[Thrs]),
    mainwait(0,Thrs),
    {_, Time1} = statistics(runtime),
    {_, Time2} = statistics(wall_clock),
    U1 = Time1 *1000 /Msgs ,
    U2 = Time2 *1000 /Msgs,
    io:format("PID=~p,TotalTime=~p(~p)ms, Avgtime= ~p (~p) usecond~n", [self(),Time1,Time2,U1, U2]),
    1+1.

mainwait(N,N) ->
        void;
mainwait(I,N) ->
        receive
                {sendordie} ->
                        io:format("I=~p,N=~p. ~n",[I,N]), 
                        mainwait(I+1,N)
        end.

sendor(PPID,Msgs) ->
                Peer = spawn(fun()->recvor(0) end),
  io:format("sendmsgs begin msg=~p,Peer=~p.~n",[Msgs,Peer]),
                sendmsgs(1, Msgs,Peer),
  io:format("sendmsgs end msg=~p,Peer=~p.~n",[Msgs,Peer]),
                Peer!{die},
                PPID!{sendordie},
  io:format("sendor die PPID=~p, pid=~p,msgnum=~p.~n",[PPID,self(),Msgs]).

sendmsgs(N,N,PID) -> 
                PID!{testmsg,["1234567890abcdefghijklmnopqrstuvwxyz#$%^ABCDEFGHIJ",9999999,999999.99,1234567890123,eeooff]};
sendmsgs(I,N,PID) -> 
                PID!{testmsg,["1234567890abcdefghijklmnopqrstuvwxyz#$%^ABCDEFGHIJ",9999999,999999.99,1234567890123,eeooff]},
                sendmsgs(I+1,N,PID).

recvor(N) ->
                receive
                        {die} -> 
        io:format("recvor dir ~p.~n",[self()]),
        void;
                        {testmsg,_} -> recvor(N+1)
                end.
for(N, N, F) ->
    [F()];
for(I, N, F) ->
    [F()|for(I+1, N, F)].
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值