Erlang进程创建时间统计及SMP现象.
来源:互联网 发布:网贷推广代理平台源码 编辑:程序博客网 时间:2024/05/16 08:41
看到Erlang编程指南里面的一个"进程创建"的性能基准测试,想放到我的环境里面用来对比一下打开SMP和关闭SMP的情况下的性能差异,结果和我未测试前想象的有点不一样.
#用例 1, 创建的进程之间有单向的消息发送. SMP 4:4
7> timer:tc(create_process, start, [100000]).
{234828,ok} %%创建10w个进程, 花费了0.23秒
8> timer:tc(create_process, start, [1000000]).
{2283906,ok} %%创建100w个进程, 花费了2.28秒
9> timer:tc(create_process, start, [10000000]).
{23277706,ok} %%创建1000w个进程, 花费了23.2秒
#用例 2, 创建的进程之间有单向的消息发送. SMP 关闭
5> timer:tc(create_process, start, [100000]).
{120949,ok} %%创建10w个进程, 花费了0.12秒
6> timer:tc(create_process, start, [10000000]).
{12299684,ok} %%创建100w个进程, 花费了1.23秒
7> timer:tc(create_process, start, [100000000]).
{122477601,ok} %%创建1000w个进程, 花费了12.2秒
从以上可以观察到两个现象:
1) Erlang创建进程的效率非常高, 100w个进程仅仅需要1,2秒的时间
2) 在打开了SMP的情况下比关闭SMP的情况下多花了近一倍的时间. 这个如何理解呢, 我开始猜测是因为在SMP打开的情形下, 不同的进程运行在不同的core上,然后跨core的进程之间的消息发送比关闭SMP的情况下同一个core上消息发送 花费的时间多,所以我猜测如果没有消息发送的话情况可能会不一样,于是我又跑了一个没有消息发送的测试.
#用例 3, 创建的进程之间无消息发送. SMP 4:4
2> timer:tc(create_process, start_wo_msg, [100000]).
{251638,ok} %%创建10w个进程, 花费了0.25秒
3> timer:tc(create_process, start_wo_msg, [1000000]).
{2211583,ok} %%创建100w个进程, 花费了2.21秒
4> timer:tc(create_process, start_wo_msg, [10000000]).
{21794646,ok} %%创建1000w个进程, 花费了21.7秒
#用例 4, 创建的进程之间无消息发送. SMP 关闭
2> timer:tc(create_process, start_wo_msg, [100000]).
{116281,ok} %%创建10w个进程, 花费了0.12秒
3> timer:tc(create_process, start_wo_msg, [1000000]).
{1132018,ok} %%创建100w个进程, 花费了1.13秒
4> timer:tc(create_process, start_wo_msg, [10000000]).
{10354658,ok} %%创建1000w个进程, 花费了10.4秒
情况貌似没有什么变化, 那说明SMP多出来的时间并不是跨core的消息发送导致的, 那估计就是不同调度器的通信之间的额外花销了, 于是我们再做一个测试来验证一下是不是调度器之间的通信导致了多出来的时间花销
#用例 5, 创建的进程之间无消息发送. SMP 4:1 ,只开启一个online scheduler, 没有scheduler之间的通信
2> timer:tc(create_process, start_wo_msg, [100000]).{196128,ok} %%创建10w个进程, 花费了0.196秒
3> timer:tc(create_process, start_wo_msg, [1000000]).
{1818807,ok} %%创建100w个进程, 花费了1.81秒
4> timer:tc(create_process, start_wo_msg, [10000000]).
{18484187,ok} %%创建1000w个进程, 花费了18.4秒
情况确实有所改善, 说明不同的调度器之间的通信确实有一些额外的时间消耗,但是这个也只是原因之一, 还有很多时间空缺没有发现是什么消耗的, 再推测推测, 估计是调度器计算分配进程到不同的core上这个过程占用了大部分的额外时间, 再来一个测试.
#用例 6 创建的进程之间无消息发送. SMP 1:1 ,只配置一个逻辑内核. 这个用例
2> timer:tc(create_process, start_wo_msg, [100000]).{182929,ok} %%创建10w个进程, 花费了0.182秒
3> timer:tc(create_process, start_wo_msg, [1000000]).
{1708805,ok} %%创建100w个进程, 花费了1.71秒
4> timer:tc(create_process, start_wo_msg, [10000000]).
{16924503,ok} %%创建1000w个进程, 花费了16.9秒
我理解这个配置SMP N:1,应该是没有什么区分的,只是说你在Erlang虚拟机启动之后有机会改变online scheduler的值(小于等于N) . 只要是只有一个online scheduler那其实就只有一个逻辑处理器被占用了,也就是说multi core的利用是由online scheduler来决定的. 假设系统有八个core,如果配置为8:4, 那CPU的利率率可以到400%, 如果是8:6, CPU的利用率可以到600%, 如果是N:1,那CPU的利用率可以到100%, 和N无关.
#用例 7 创建的进程之间无消息发送, SMP 1:1 尝试用+sbt选项绑定scheduler.
实验了各种组合, ns, ts, ps, sct,情况, 测试结果基本和未绑定一致, 那只能猜测是, 在指定SMP 的情况下, Erlang虚拟机或者系统本身还有会有不少额外的消耗的.
从下面可见, 即使是SMP 1:1, Erlang虚拟机也额外为每个core启动了一个系统进程.
# SMP 1:1
kilxxen2768: ~ > pstree -p 26457
beam.smp(26457)-+-erl_child_setup(26477)
|-{beam.smp}(26472)
|-{beam.smp}(26476)
|-{beam.smp}(26478)
`-{beam.smp}(26479)
#关闭SMP的情况
kilxxen2768: ~ > pstree -p 421
beam(421)---erl_child_setup(439)
#用例 8 创建的进程之间无消息发送, SMP 1:1 , 用taskset绑定Erlang进程到指定的CPU Core 3上面
用linux命令手动绑定Erlang进程到指定的core上, 执行时间没有变化.
beam.smp(26457)-+-erl_child_setup(26477)
|-{beam.smp}(26472)
|-{beam.smp}(26476)
|-{beam.smp}(26478)
`-{beam.smp}(26479)
kilxxen2768: ~ > taskset -cp 3 26457
kilxxen2768: ~ > taskset -cp 3 26477
kilxxen2768: ~ > taskset -cp 3 26472
kilxxen2768: ~ > taskset -cp 3 26476
kilxxen2768: ~ > taskset -cp 3 26478
kilxxen2768: ~ > taskset -cp 3 26479
测试代码文件 create_process.erl
-module(create_process).
-compile(export_all).
%% 启动Num个进程,且进程之间有消息发送
start(Num)->
start_proc(Num, self()).
start_proc(0, Pid)->
Pid ! ok;
start_proc(Num, Pid)->
NPid = spawn(?MODULE, start_proc,[Num-1, Pid]),
NPid!ok,
receive ok-> ok end.
%%启动Num个进程,进程之间无消息发送
start_wo_msg(0)->
ok;
start_wo_msg(Num)->
spawn(?MODULE, run, []),
start_wo_msg(Num-1).
run() ->
ok.
测试环境
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 4
Vendor ID: GenuineIntel
CPU family: 6
Model: 45
Stepping: 7
CPU MHz: 2400.038
BogoMIPS: 4807.41
Hypervisor vendor: Xen
Virtualization type: para
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 20480K
##博客仅作个人记录##
- Erlang进程创建时间统计及SMP现象.
- [Erlang 0035] Erlang SMP
- erlang创建进程
- 创建子进程统计文件个数及文件名
- erlang性能分析及进程监控工具
- erlang 进程消息及ets性能测试
- erlang性能分析及进程监控工具
- Erlang example——创建进程和进程通信
- 关于Erlang和SMP的一些说明
- 关于Erlang和SMP的一些说明
- [Erlang]时间函数及时间校正机制详解
- 关于.net创建excel文件关闭进程的奇怪现象
- 守护进程及创建
- erlang 并发编程,spawn 创建新的进程
- erlang 创建一个进程所占的内存
- real,user and sys 进程时间统计
- real,user and sys 进程时间统计
- Mellanox CX4网卡SMP affinity的奇怪现象
- 我的一个小程序的功能完善问题
- [急问]关于Form获取焦点和Canvas的键盘监听的问题
- j2me发送短信在多普达上的问题一
- 正则表达式 网页处理速度慢。。怎么优化?
- 判断访问是否来自搜索引擎
- Erlang进程创建时间统计及SMP现象.
- 数字签名算法为:MD5withRSA
- 怎么在搜索蓝牙4.0 设备中调用蓝牙2.0的搜索界面?(和UI关系更大,和蓝牙4.0关系不大)
- 请教如何将一个文件夹中的所有图片上传到指定目录
- 想做个网站,但不清楚费用
- 谁能提供一个抓取网页的教程
- 为什么在我的电脑上无法搭载环境呢?
- 求救!ASP中声明全局类(自己写的)只有80分了
- 想实现一个后台定时服务