Erlang 使用HIPE SASL Monitor常用的一些参数和命令,记录于此备忘.
编译启用HIPE(High Performance Erlang)
Hipe是什么?
霸爷有一个一语中的的描述"erlang的hipe相当于jit, 根据语言评测有hipe支持在纯erlang的运算上会快2-3倍,这个性能的提升对于计算密集型的应用还是比较可观的。"
维基百科上关于Jit的资料:
即时编译(Just-in-time compilation),又称为动态翻译,是一种提高程序运行效率的方法。通常,程序有两种运行方式:静态编译与动态直译。静态编译的程序在执行前全部被翻译为机器码,而直译执行的则是一句一句边运行边翻译。
即时编译器则混合了这二者,一句一句编译源代码,但是会将翻译过的代码缓存起来以降低性能损耗。相对于静态编译代码,即时编译的代码可以处理延迟绑定并增强安全性。
即时编译器有两种类型,一是字节码翻译,二是动态编译翻译。
微软的.NET Framework[1][2],还有绝大多数的Java实现[3],都依赖即时翻译以提供高速的代码执行。
编译启用HIPE选项可以这样:c(Module,[native,{hipe,HipeOptions}|MoreOptions). 或者在Emakefile添加对应的配置节;
关于hipe选项的可用参数,我们可以通过hipe:help_options()查看,下面是在我机器上的执行结果:
Erlang R14B03 (erts-5.8.4) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.8.4 (abort with ^G)
1> hipe:help_options().
HiPE Compiler Options
Boolean-valued options generally have corresponding aliases `no_...',
and can also be specified as `{Option, true}' or `{Option, false}.
General boolean options:
[debug,load,pp_asm,pp_beam,pp_icode,pp_native,pp_rtl,time,timeout,verbose].
Non-boolean options:
o#, where 0 =< # =< 3:
Select optimization level (the default is 2).
Further options can be found below; use `hipe:help_option(Name)' for details.
Aliases:
pp_all = [pp_beam,pp_icode,pp_rtl,pp_native],
pp_sparc = pp_native,
pp_x86 = pp_native,
pp_amd64 = pp_native,
pp_ppc = pp_native,
o0,
o1 = [inline_fp,pmatch,peephole],
o2 = [icode_range,icode_ssa_const_prop,icode_ssa_copy_prop,icode_type,
icode_inline_bifs,rtl_lcm,rtl_ssa,rtl_ssa_const_prop,spillmin_color,
use_indexing,remove_comments,concurrent_comp,binary_opt] ++ o1,
o3 = [{regalloc,coalescing},icode_range] ++ o2.
ok
Note: another option is to compile your Erlang module to native code. Native code compiling is not available for every platform and OS, but on those that support it, it can make your programs go faster (about 20% faster, based on anecdotal evidence). To compile to native code, you need to use the
hipe
module and call it the following way:hipe:c(Module,OptionsList).
You could also usec(Module,[{hipe,o3}]).
when in the shell to achieve similar results. Note that the .beam file generated will no longer be portable across platforms like regular ones.
开启SASL Error Log
OTP的标准behavior都会发送进程和错误信息到error_logger(后面我会有专门的文章解释).我们可以通过添加启动参数启动sasl
erl -boot start_sasl
这样启动之后信息是输出在shell中,可以通过添加配置来让信息记录到文本,然后通过rb:start来查看;这里<Erlang程序设计>中已经有详细的例子,这里不再赘述.
进程单向监控-Monitor
link方式可以建立进程之间的双向链接关系,我们可以通过monitor实现单向的监控,这在gen_server代码里面可以看到对应的例子
- erlang:monitor(process, Caller), %建立单向监控
- 被监控进程死掉发送的消息规格: {'DOWN',Mref,process,Pid,Reason}
- 解除监控:erlang:demonitor(Ref)
gen_server代码片段:
do_multi_call(Nodes, Name, Req, Timeout) ->
Tag = make_ref(),
Caller = self(),
Receiver =
spawn(
fun() ->
%% Middleman process. Should be unsensitive to regular
%% exit signals. The sychronization is needed in case
%% the receiver would exit before the caller started
%% the monitor.
process_flag(trap_exit, true),
Mref = erlang:monitor(process, Caller), %建立单向监控
receive
{Caller,Tag} ->
Monitors = send_nodes(Nodes, Name, Tag, Req),
TimerId = erlang:start_timer(Timeout, self(), ok),
Result = rec_nodes(Tag, Monitors, Name, TimerId),
exit({self(),Tag,Result});
{'DOWN',Mref,_,_,_} -> %接受监控消息
%% Caller died before sending us the go-ahead.
%% Give up silently.
exit(normal)
end
end),
Mref = erlang:monitor(process, Receiver),
Receiver ! {self(),Tag},
receive
{'DOWN',Mref,_,_,{Receiver,Tag,Result}} ->
Result;
{'DOWN',Mref,_,_,Reason} ->
%% The middleman code failed. Or someone did
%% exit(_, kill) on the middleman process => Reason==killed
exit(Reason)
end.