[Erlang0016]Erlang三則之HIPESASLMonitor

唐玄奘發表於2017-12-03

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 use c(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.

 


相關文章