前篇文章[url] 講述了如何啟用erlang hipe支援,但是使用者程式大量依賴的標準庫如stdlib, kernel等預設都不是native模式的, 所以我們的程式雖然啟用了hipe,但是只是部分啟用了。用oprofile等工具可以看到我們的程式還是在process_main(虛擬機器的**解釋在這裡)裡面打轉。 我們來個極致的,通通hipe化。
有2個方案可以解決:
1. 在編譯otp_src的時候 export erl_compile_flags='+native +""' 但是這個方案有個問題就是
native方式是和beam的模式有關的 如beam和beam.smp它的**是不同的,但是所有的beam又公用一套庫,這樣只能捨棄乙個了。所以這個方案就比較麻煩。
# erl
erlang r13b01 (erts-5.7.2) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]
eshell v5.7.2 (abort with ^g)
1> %%沒問題
#erl -smp disable
warning: not loading native code for module fib: it was compiled for an incompatible runtime system; please regenerate native code for this runtime system
....
erlang r13b01 (erts-5.7.2) [source] [64-bit] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]
eshell v5.7.2 (abort with ^g)
1>
這個也可以通過修改 alias erl=erl -smp disable 以便欺騙編譯器生成單cpu模式的beam
去繞過去
2. 動態編譯, 等系統執行起來以後,動態把相關的模組編譯一遍,這個思路看起來最簡單。
我做了個原型 證明這樣是可行的。。。
# cat hi.erl
-module(hi).
-export([do/0]).
do()->
[ turn(m, p)|| <-code:all_loaded(), p=/=preloaded].
turn(m, p) ->
p1 = binary_to_list(iolist_to_binary(re:replace(filename:join(filename:dirname(p), filename:basename(p, ".beam")), "ebin", "src"))),
l = m:module_info(),
copts = get_compile_options(l),
copts1 = lists:foldr(fun(, acc) when is_list(v) and is_integer(hd(v)) -> ++ acc ; (skip, acc) -> acc ++ [skip] end, , copts),
c:c(p1, copts1 ++ [native, ""]).
tr(p)->
binary_to_list(iolist_to_binary(re:replace(p, "/net/isildur/ldisk/daily_build/otp_prebuild_r13b01.2009-06-07_20/", "/home/yufeng/"))). %%%這個地方要根據實際情況調整 具體的參看 m(lists).
get_compile_options(l) ->
case get_compile_info(l, options) of
-> val;
error ->
end.
get_compile_info(l, tag) ->
case lists:keysearch(compile, 1, l) of
} ->
case lists:keysearch(tag, 1, i) of
} -> ;
false -> error
end;
false -> error
end.
#erl -nostick
erlang r13b01 (erts-5.7.2) [source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]
eshell v5.7.2 (abort with ^g)
1> mnesia:start(). %啟動我們的應用程式
ok2> hi:do().[,,
,,,,
,,,,
,,,,
,,,,
,,,,
,,,,
,,|...]
3> m(dict).
module dict compiled: date: august 23 2009, time: 17.20
compiler options: [,,,
,debug_info,[color=red]native,""[/color]]
object file: /home/yufeng/otp_src_r13b01/lib/stdlib/src/../ebin/dict.beam
。。。看到了是用native模式編譯的哦。。。
不過編譯過程中有幾個模組是有點問題, 得改進下。
C 標準庫高階1
一 容器的選擇 一般情況下,最容易想到也最常用的就是vector,但是如果要是頻繁在容器物件的中間刪除和插入元素,就要考慮使用list,因為list是基於節點的容器,當頻繁在容器中間刪除和插入元素時,不需要將很多元素整體向前或者向後移動,只需要操作節點元素指標指向的位置,效率較高且不會導致迭代器失效...
C 標準庫高階2
十 把容器資料傳給舊的介面 1.vector傳入陣列型api void stlwitholdapi int ps,size t num if v.empty return 0 先判段容器是否為空,然後傳入容器首元素的位址和長度即可 2.string傳入字串api void stlwitholdapi...
C 標準庫高階6
二十 二 函式指標和函式呼叫運算子的效率 使用less的sort呼叫比使用inline comp的sort呼叫快 原因是因為函式內聯。less operator 函式物件的operator 函式是內聯的,operator 的函式體可以直接被編譯器使用,直接在呼叫處進行展開。所以,sort中不包含函式...