浏览 2257 次
锁定老帖子 主题:系统标准库的hipe支持(高级)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-08-23
最后修改:2009-08-23
http://mryufeng.iteye.com/blog/428845 讲述了如何启用erlang hipe支持,但是用户程序大量依赖的标准库如stdlib, kernel等默认都不是native模式的, 所以我们的程序虽然启用了hipe,但是只是部分启用了。用oprofile等工具可以看到我们的程序还是在process_main(虚拟机的代码解释在这里)里面打转。 我们来个极致的,通通hipe化。
前篇文章有2个方案可以解决: 1. 在编译otp_src的时候 export ERL_COMPILE_FLAGS='+native +"{hipe, [o3]}"' 但是这个方案有个问题就是 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 <HiPE (v 3.7.2)> 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)|| {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({K, V}, Acc) when is_list(V) and is_integer(hd(V)) ->[{K, tr(V)}] ++ Acc ; (Skip, Acc) -> Acc ++ [Skip] end, [], COpts), c:c(P1, COpts1 ++ [native, "{hipe, [o3]}"]). 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 {ok,Val} -> Val; error -> [] end. get_compile_info(L, Tag) -> case lists:keysearch(compile, 1, L) of {value, {compile, I}} -> case lists:keysearch(Tag, 1, I) of {value, {Tag, Val}} -> {ok,Val}; 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(). %启动我们的应用程序 ok 2> hi:do(). [{ok,io}, {ok,erl_distribution}, {ok,edlin}, {ok,error_handler}, {ok,io_lib}, {ok,hi}, {ok,filename}, {ok,orddict}, {ok,gb_sets}, {ok,inet_db}, {ok,inet}, {ok,ordsets}, {ok,group}, {ok,gen}, {ok,erl_scan}, {ok,kernel}, {ok,erl_eval}, {ok,ets}, {ok,lists}, {ok,sets}, {ok,inet_udp}, {ok,code}, {ok,ram_file}, {ok,dict}, {ok,packages}, {ok,gen_event}, {ok,heart}, {ok,...}, {...}|...] 3> m(dict). Module dict compiled: Date: August 23 2009, Time: 17.20 Compiler options: [{cwd,"/home/yufeng/otp_src_R13B01/lib/stdlib/src"}, {outdir,"/home/yufeng/otp_src_R13B01/lib/stdlib/src/../ebin"}, {i,"/home/yufeng/otp_src_R13B01/lib/stdlib/src/../include"}, {i,"/home/yufeng/otp_src_R13B01/lib/stdlib/src/../../kernel/include"}, debug_info,native,"{hipe, [o3]}"] Object file: /home/yufeng/otp_src_R13B01/lib/stdlib/src/../ebin/dict.beam 。。。 看到了是用native模式编译的哦。。。 不过编译过程中有几个模块是有点问题, 得改进下。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-08-23
源码编译的时候用这招:
alias erl="erl -smp disable" export ERLC_EMULATOR="erl -smp disable" 搞定native和emulator相关的问题。 it rocks! |
|
返回顶楼 | |
发表时间:2009-08-23
测试效果很好:
速度提高了百分之大几十! |
|
返回顶楼 | |
发表时间:2009-08-23
这个操作 http://avindev.iteye.com/blog/82560
编译选项 c(test_list, [native,{hipe,[o3]}]). R13B02 stdlib hipe before: 1> test_list:main(). Concat Duration 390ms Flatten Duration 938ms Append tail Duration 622ms Append header Duration 85ms R13B02 stdlib hipe after: 1> test_list:main(). Concat Duration 146ms Flatten Duration 736ms Append tail Duration 222ms Append header Duration 53ms |
|
返回顶楼 | |
发表时间:2009-09-20
hipe:c(Module) 更能解决问题。
|
|
返回顶楼 | |
发表时间:2009-11-03
哈哈,这招真的是太狠了,佩服.
正在使用老大的方式编译hipe. 好象在5.7.3上面运行 erl -smp disable hipe没有爆warning linux:~ # erl -smp disable Erlang R13B02 (erts-5.7.3) [source] [rq:1] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.7.3 (abort with ^G) 1> |
|
返回顶楼 | |
发表时间:2009-11-03
请问一下
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). 中的路径,主要是看m(lists)中的哪个路径啊? 谢谢 |
|
返回顶楼 | |
发表时间:2009-11-03
已经看懂了,呵呵,谢谢.
|
|
返回顶楼 | |