Last active
August 29, 2015 14:10
-
-
Save sile/b9a7c1ccee028f6cce5a to your computer and use it in GitHub Desktop.
HiPE(High Performance Erlang)について ref: http://qiita.com/sile/items/d750019fcab961bbb0a7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% 一応、gb_trees以外にも使えるようになっている | |
-module(bench). | |
-export([do_bench/5]). | |
%% @doc マップ(的なデータ構造)の構築時間と検索時間を測定する | |
do_bench(MapInit, StoreFun, FindFun, Input, Keys) -> | |
erlang:garbage_collect(), | |
{StoreTime, Map} = | |
timer:tc(fun () -> store_loop(MapInit, StoreFun, Input) end), | |
erlang:garbage_collect(), | |
{FindTime, _} = | |
timer:tc(fun () -> find_loop(Map, FindFun, Keys) end), | |
[ | |
{store_time, StoreTime / (1000 * 1000)}, | |
{find_time, FindTime / (1000 * 1000)} | |
]. | |
store_loop(Map, _, []) -> | |
Map; | |
store_loop(Map, StoreFun, [{K, V} | List]) -> | |
store_loop(StoreFun(K, V, Map), StoreFun, List). | |
find_loop(_, _, []) -> | |
ok; | |
find_loop(Map, FindFun, [K | List]) -> | |
FindFun(K, Map), | |
find_loop(Map, FindFun, List). | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% かなり適当な実装のechoサーバプロセス | |
-module(echo). | |
-export([start/0, call/2, call_n/3]). % external functions | |
-export([loop/0]). % internal functions | |
%% @doc echoサーバを起動する | |
-spec start() -> {ok, pid()}. | |
start() -> | |
{ok, spawn(?MODULE, loop, [])}. | |
%% @doc echoサーバにリクエストを投げる | |
-spec call(Server::pid(), Request::term()) -> Response::term(). | |
call(Server, Request) -> | |
Server ! {self(), Request}, | |
receive | |
Response -> Response | |
end. | |
%% @doc echoサーバに`Count'回だけリクエストを投げる | |
-spec call_n(Server::pid(), Request::term(), Count::non_neg_integer()) -> ok. | |
call_n(_Server, _Request, 0) -> | |
ok; | |
call_n(Server, Request, Count) -> | |
Request = call(Server, Request), | |
call_n(Server, Request, Count - 1). | |
-spec loop() -> no_return(). | |
loop() -> | |
receive | |
{From, Request} -> | |
From ! Request, % 送られてきたリクエストをそのまま返す | |
?MODULE:loop() | |
end. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
int fib(int n) { | |
if (n < 2) { | |
return 1; | |
} | |
return fib(n - 2) + fib(n - 1); | |
} | |
int main(int argc, char ** argv) { | |
int n = atoi(argv[1]); | |
printf("%d: %d\n", n, fib(n)); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(fib). | |
-export([fib/1]). | |
fib(N) when not is_integer(N) -> | |
error(badarg, [N]); % 引数の型が不正ならbadarg例外を投げるように変更 | |
fib(N) when N < 2 -> | |
1; | |
fib(N) -> | |
fib(N - 2) + fib(N - 1). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(fib2). | |
-export([fib2/1]). | |
fib2(N) -> fib:fib(N) + fib:fib(N). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ソースコードの取得 | |
$ wget http://www.erlang.org/download/otp_src_17.3.tar.gz | |
$ tar zxf otp_src_17.3.tar.gz | |
$ cd otp_src_17.3 | |
# '--enable-hipe'を指定してビルド&インストール | |
$ ./configure --enable-hipe ...他のオプションは省略... | |
$ make | |
$ sudo make install | |
# 起動: 起動メッセージに'[hipe]'という文言が含まれていたらHiPEが有効(利用可能)になっている | |
$ erl | |
Erlang/OTP 17 [erts-6.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] | |
Eshell V6.2 (abort with ^G) | |
1> q(). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 最適化なし | |
$ gcc -o fib fib.c | |
$ time ./fib 40 | |
40: 165580141 | |
real 0m0.678s | |
user 0m0.676s | |
sys 0m0.000s | |
# 最適化あり | |
$ gcc -O3 -o fib fib.c | |
$ time ./fib 40 | |
40: 165580141 | |
real 0m0.287s | |
user 0m0.286s | |
sys 0m0.000s |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% HiPEなし | |
> c(echo). | |
> {ok, Pid} = echo:start(). % 起動 | |
> echo:call(Pid, hello). % 動作確認 | |
hello | |
> Time(fun () -> echo:call_n(Pid, hello, 1000000) end). % 100万回のリクエストを処理するまでに掛かる時間 | |
0.746382 % 0.74秒 | |
> exit(Pid, kill), f(Pid). % 後始末 | |
%% HiPEあり | |
> c(echo, [native]). | |
> {ok, Pid} = echo:start(). % 起動 | |
> Time(fun () -> echo:call_n(Pid, hello, 1000000) end). % 100万回のリクエストを処理するまでに掛かる時間 | |
0.739132 % 0.73秒 | |
> exit(Pid, kill), f(Pid). % 後始末 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% 下準備: | |
%% $ cp ${OTP_17_3_SOURCE}/lib/stdlib/src/gb_trees.erl . | |
> code:unstick_mod(gb_trees). % 標準モジュールを上書き可能にする | |
true | |
> c(bench, [native]). | |
{ok, bench}. | |
> Input = [{random:uniform(1000000), N} || N <- lists:seq(1, 200000)]. % 入力データを20万個用意する | |
> Keys = [K || {K, _} <- Input]. % 検索に使用するキーセット (成功探索のみ) | |
%% HiPEなし | |
> c(gb_trees). | |
> bench:do_bench(gb_trees:empty(), fun gb_trees:enter/3, fun gb_trees:lookup/2, Input, Keys). | |
[{store_time,0.489443}, % 構築時間: 0.48秒 | |
{find_time, 0.169788}] % 検索時間: 0.16秒 | |
%% HiPEあり | |
> c(gb_trees, [native]). | |
> bench:do_bench(gb_trees:empty(), fun gb_trees:enter/3, fun gb_trees:lookup/2, Input, Keys). | |
[{store_time,0.29301}, % 構築時間: 0.29秒 | |
{find_time,0.107849}] % 検索時間: 0.10秒 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ erl | |
Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false] | |
Eshell V5.10.4 (abort with ^G) | |
%% 上でHiPEコンパイルされていたfibモジュールをロードする | |
1> l(fib). | |
{module,fib} | |
%% HiPEの互換性が無い、というエラーメッセージが表示される | |
=INFO REPORT==== 2-Dec-2014::02:44:44 === | |
<HiPE (v 3.10.2.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 | |
2> code:is_module_native(fib). | |
false % HiPEは有効になっていない | |
3> fib:fib(10). | |
89 % 実行することは可能 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# OTP17-3のgb_treesモジュールの例 | |
# 行数 | |
$ wc -l gb_trees.erl | |
553 gb_trees.erl | |
# erlcコマンド自体の実行時間 | |
$ time erlc | |
real 0m0.190s | |
user 0m0.023s | |
sys 0m0.239s | |
# HiPEなしのコンパイル時間 | |
$ time erlc gb_trees.erl | |
real 0m0.419s % 0.419 - 0.190 = 0.228s | |
user 0m0.108s | |
sys 0m0.483s | |
# HiPEありのコンパイル時間 | |
real 0m0.907s % 0.907 - 0.190 = 0.717s | |
user 0m0.495s | |
sys 0m1.065s |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# HiPEなし | |
$ erlc gb_trees.erl | |
$ du -h gb_trees.beam | |
8.0K gb_trees.beam | |
# HiPEあり | |
$ erlc +native gb_trees.erl | |
$ du -h gb_trees.beam | |
28K gb_trees.beam |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% dictなら成功 | |
> code:unstick_mod(dict). | |
> l(dict). | |
> hipe:c(dict). | |
{ok, dict}. | |
%% cryptoなら失敗 | |
> l(crypto). | |
> hipe:c(crypto). | |
<HiPE (v 3.11)> EXITED with reason {'trans_fun/2',on_load} @hipe_beam_to_icode:1174 | |
=ERROR REPORT==== 2-Dec-2014::04:02:45 === | |
Error in process <0.120.0> with exit value: {{badmatch,{'EXIT',{{hipe_beam_to_icode,1174,{'trans_fun/2',on_load}},[{hipe_beam_to_icode,trans_fun,2,[]},{hipe_beam_to_icode,trans_fun,2,[]},{hipe_beam_to_icode,trans_mfa_code,5,[]},{hipe_beam_to_icode,trans_beam_function_chunk... | |
** exception exit: {{badmatch,{'EXIT',{{hipe_beam_to_icode,1174, | |
{'trans_fun/2',on_load}}, | |
[{hipe_beam_to_icode,trans_fun,2,[]}, | |
{hipe_beam_to_icode,trans_fun,2,[]}, | |
{hipe_beam_to_icode,trans_mfa_code,5,[]}, | |
{hipe_beam_to_icode,trans_beam_function_chunk,2,[]}, | |
{hipe_beam_to_icode,'-module/2-lc$^1/1-1-',2,[]}, | |
{hipe_beam_to_icode,'-module/2-lc$^1/1-1-',2,[]}, | |
{hipe,get_beam_icode,4,[]}, | |
{hipe,'-run_compiler_1/3-fun-0-',4,[]}]}}}, | |
[{hipe,get_beam_icode,4,[]}, | |
{hipe,'-run_compiler_1/3-fun-0-',4,[]}, | |
{erl_pp,attribute,2,[]}]} | |
in function hipe:run_compiler_1/3 | |
in call from hipe:run_compiler/4 | |
in call from hipe:c/3 | |
...以下略... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% HiPEなし | |
> c(hoge). | |
{ok, hoge}. | |
> code:is_module_native(hoge). % code:is_module_native/1で判定可能 | |
false | |
> hoge:hoge(). | |
hoge | |
%% HiPEあり | |
> c(hoge, [native]). | |
{ok, hoge}. | |
> code:is_module_native(hoge). | |
true | |
> hoge:hoge(). | |
hoge |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> c(fib). | |
> c(fib2). | |
> fib:fib(10). | |
89 | |
> fib2:fib2(10). | |
178 | |
%% 例外発生: HiPEなし | |
> c(fib). | |
> try fib2:fib2(xxx) catch error:badarg -> erlang:get_stacktrace() end. | |
[{fib,fib,[xxx], % 例外送出元関数の引数の情報が載る | |
[{file,"fib.erl"},{line,8}]}, % 行番号もつく | |
{fib2,fib2,1,[{file,"fib2.erl"},{line,6}]}, | |
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,661}]}, | |
{erl_eval,try_clauses,8,[{file,"erl_eval.erl"},{line,891}]}] | |
%% 例外発生: HiPEあり | |
> c(fib, [native]). | |
[{fib,fib,1,[]}, % 引数の数(arity)だけしか情報がない | |
{erl_pp,attribute,2,[]}, % fib2:fib2/1を経由しているという情報も消えている | |
{shell,exprs,7,[]}, | |
{shell,eval_exprs,7,[]}, | |
{shell,eval_loop,3,[]}, | |
{erl_pp,attribute,2,[]}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% fibモジュールをHiPEなしでコンパイル | |
> c(fib). | |
{ok,fib} | |
%% recon_traceを使ってトレース | |
> recon_trace:calls({fib, fib, fun (_) -> return_trace() end}, 10). | |
1 % トレース対象の関数の数 | |
> fib:fib(10). | |
89 | |
4:46:10.951606 <0.33.0> fib:fib(10) % トレース結果が表示される | |
4:46:10.957504 <0.33.0> fib:fib/1 --> 89 | |
%% fibモジュールをHiPEありでコンパイル | |
> c(fib, [native]). | |
{ok,fib}. | |
%% recon_traceを使ってトレース | |
> recon_trace:calls({fib, fib, fun (_) -> return_trace() end}, 10). | |
0 % トレース対象が存在しない | |
> fib:fib(10). | |
89 % 実行しても特に何も表示されない |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% 'o0'から'o3'まで最適化レベルを指定可能 (それぞれの詳細は後述) | |
> c(hoge, [native, {hipe, [o0]}]). % 最適化なし | |
> c(hoge, [native, {hipe, [o1]}]). | |
> c(hoge, [native, {hipe, [o2]}]). % デフォルト | |
> c(hoge, [native, {hipe, [o3]}]). % 最高レベル |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> c(hoge, [native, {hipe, [to_llvm]}]). % 'to_llvm'オプションを指定する |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> hipe:module_info(exports). | |
[{load,1}, | |
{c,1}, | |
{c,2}, | |
{f,1}, | |
{f,2}, | |
{compile,1}, | |
{compile,2}, | |
{compile_core,4}, | |
{file,1}, | |
{file,2}, | |
{version,0}, | |
{help,0}, | |
{help_hiper,0}, | |
{help_options,0}, | |
{help_option,1}, | |
{help_debug_options,0}, | |
{llvm_support_available,0}, | |
{module_info,0}, | |
{module_info,1}, | |
{compile,4}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% | |
%% 全体ヘルプ | |
%% | |
> hipe:help(). | |
The HiPE Compiler (Version 3.11) | |
The normal way to native-compile Erlang code using HiPE is to | |
include `native' in the Erlang compiler options, as in: | |
1> c(my_module, [native]). | |
Options to the HiPE compiler must then be passed as follows: | |
1> c(my_module, [native,{hipe,Options}]). | |
Use `help_options()' for details. | |
Utility functions: | |
help() | |
Prints this message. | |
help_options() | |
Prints a description of options recognized by the | |
HiPE compiler. | |
help_option(Option) | |
Prints a description of that option. | |
help_debug_options() | |
Prints a description of debug options. | |
version() -> | |
Returns the HiPE version as a string'. | |
For HiPE developers only: | |
Use `help_hiper()' for information about HiPE's low-level interface | |
ok | |
%% | |
%% HiPE用のコンパイルオプションの説明 | |
%% | |
> 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, % o0〜o3までの最適化オプションの実態もここで分かる | |
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 | |
%% | |
%% 個別オプションの詳細表示 | |
%% | |
> hipe:help_option(icode_range). | |
icode_range - Performs integer range analysis on the Icode level | |
ok | |
> hipe:help_option(to_llvm). | |
This is an alias for: [to_llvm,{llvm_opt,o3},{llvm_llc,o3}]. | |
ok |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% まずバイトコードコンパイル | |
> c(hoge). | |
{ok, hoge}. | |
%% 下記コマンドを別のシェルで実行 | |
%% $ mv hoge.erl h.erl | |
> ls("hoge.beam"). | |
hoge.beam | |
ok | |
> ls("hoge.erl"). | |
no such file or directory | |
ok | |
%% hipeモジュールを直接使ってHiPEコンパイル | |
> hipe:c(hoge). | |
{ok, hoge}. % beamファイルだけでコンパイルが可能 | |
%% 通常のコンパイル関数経由でHiPEコンパイル | |
> c(hoge, [native]). | |
hoge.erl: no such file or directory | |
error % ソースファイルがないと怒られる |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% 処理時間計測用の補助関数を準備 | |
> Time = fun (Fun) -> {MicroSeconds, _} = timer:tc(Fun), MicroSeconds / (1000 * 1000) end. | |
#Fun<erl_eval.6.90072148> | |
%% N=40の場合のフィボナッチ数を求めるのに掛かる時間を計測する | |
> fib:fib(40). | |
165580141 | |
%% HiPEなし | |
> c(fib). | |
> Time(fun () -> fib:fib(40) end). | |
5.325893 % 5.32秒 | |
%% HiPEあり: デフォルトオプション | |
> c(fib, [native]). | |
> Time(fun () -> fib:fib(40) end). | |
1.167685 % 1.16秒 | |
%% HiPEあり: 最適化レベル最高 | |
> c(fib, [native, {hipe, [o3]}]). | |
> Time(fun () -> fib:fib(40) end). | |
1.166181 % 1.16秒 (今回のケースでは、デフォルト(o2)とほとんど差異なし) | |
%% HiPEあり: LLVMバックエンド | |
> c(fib, [native, {hipe, [to_llvm]}]). | |
> Time(fun () -> fib:fib(40) end). | |
1.076048 % 1.07秒 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%% サンプルモジュール | |
-module(hoge). | |
-export([hoge/0]). | |
hoge() -> hoge. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment