Archive

Archive for August, 2009

转:CPU密集型计算 erlang和C 大比拼

August 30th, 2009 Comments off

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 转:CPU密集型计算 erlang和C 大比拼

原文地址:http://pseudelia.wordpress.com/2009/08/23/erlang-native-code-benchmark/

Normalerweise compiliert Erlang Bytecode (heißt das so in Erlang?). Das coole daran ist, dass man die beam files leicht auf anderen Rechnern benutzen kann. Aber die Geschwindigkeit von diesem Code hat mich nicht überzeugen können. Darum habe ich ausprobiert wie gut der native Code ist den Erlang baut.

Der Versuchsaufbau ist einfach: Ich habe eine simple rekursive Funktion geschrieben, die Fibonaccizahlen berechnet. Dann wir 5-mal Fibonacci von 40 berechnet und die Zeit gemessen. Das ganze mache ich mit nur einem Kern. Diesen Test mache ich insgesamt 3-mal. Einmal mit nativem Erlangcode, einmal mit nicht nativem Erlangcode und einmal mit einem in C geschriebenen Programm. Der Benchmark besteht aus drei Dateien:

cpu_intensive.erl:

-module(cpu_intensive).
-compile(export_all).

fib_test() ->
 fib(40), fib(40), fib(40), fib(40), fib(40).

fib(0) -> 1;
fib(1) -> 1;
fib(N) -> fib(N-1) + fib(N-2).

cpu_intensive.c

unsigned int fib(unsigned int n) {
 if (n == 0 || n == 1) {
 return 1;
 }
 return fib(n-1) + fib(n-2);
}

int main() {
 fib(40); fib(40); fib(40); fib(40); fib(40);
 return 0;
}

Makefile:
all: native normal c

native:
@erlc +native cpu_intensive.erl
@echo “”
@echo “Fibonacci Erlang native code”
@time erl -noshell -s cpu_intensive fib_test -s erlang halt

normal:
@erlc cpu_intensive.erl
@echo “”
@echo “Fibonacci Erlang non-native code”
@time erl -noshell -s cpu_intensive fib_test -s erlang halt

c:
@gcc -O0 -o cpu_intensive cpu_intensive.c
@echo “”
@echo “Fibonacci written in C without optimizations”
@time ./cpu_intensive
Ich habe obige drei Dateien angelegt und die Makefile ausgeführt. Das Ergebnis war bei meinem Core 2 Duo 8400

Fibonacci Erlang native code
13,99 real        13,00 user         0,95 sys

Fibonacci Erlang non-native code
116,81 real       115,46 user         1,00 sys

Fibonacci written in C without optimizations
11,14 real        11,10 user         0,00 sys

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , ,

erlang到底能够并发发起多少系统调用

August 25th, 2009 5 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: erlang到底能够并发发起多少系统调用

为了测试下erlang的多smp能够每秒并发发起多少系统调用,这个关系到erlang作为网络程序在高并发下的评估。

首先crack下otp_src,因为erlang:now() 是调用了clock_gettime这个系统调用,但是遗憾的是这个now里面设计到很多mutex会导致不可预期的futex调用,所以需要做如下修改,
调用最廉价的getuid系统调用:

root@ubuntu:~# emacs otp_src_R13B/erts/emulator/beam/erl_bif_info.c
BIF_RETTYPE statistics_1(BIF_ALIST_1)
{
Eterm res;
Eterm* hp;

if (BIF_ARG_1 == am_context_switches) {
Eterm cs = erts_make_integer(erts_get_total_context_switches(), BIF_P);
hp = HAlloc(BIF_P, 3);
res = TUPLE2(hp, cs, SMALL_ZERO);
BIF_RET(res);
<span style="color: red;"> } else if (BIF_ARG_1 == am_ok) { /* Line 2713 */
getuid();
BIF_RET( am_ok);
</span> } else if (BIF_ARG_1 == am_garbage_collection) {
...
}

重新make下otp_src

[root@localhost ~]# cat tsmp.erl
-module(tsmp).
-export([start/1]).

loop(I, N)->;
%%   erlang:now(),
%%   os:timestamp(),
erlang:statistics(ok), %% call getuid

case N rem 100000 of
0 ->;
io:format("#~p:~p~n", [I, N]);
_->;
skip
end,

loop(I, N + 1).

start([X])->;
N = list_to_integer(atom_to_list(X)),
[spawn_opt(fun () -> loop(I, 0) end, [{scheduler, I}]) || I <-lists:seq(1, N)],
receive
stop ->;
ok
after 60000 ->;
ok
end,
init:stop().
#otp_src_R13B02/bin/erl  -sct db  -s tsmp start 8
。。。
#7:226500000
#1:228000000
#8:152600000
#5:150200000
#4:225600000
#3:222000000
#2:224000000
#6:226400000
#7:226600000
#1:228100000
#4:225700000
#8:152700000
#3:222100000

对其中一个调度器线程的trace

[root@wes263 ~]#  /usr/bin/strace  -c -p 4667
Process 4667 attached - interrupt to quit
PANIC: attached pid 4667 exited with 0
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
99.87    0.230051           0   3979319           getuid
0.08    0.000189           0      1924           poll
0.05    0.000116           0      1924           clock_gettime
0.00    0.000000           0       147        48 futex
------ ----------- ----------- --------- --------- ----------------
100.00    0.230356               3983314        48 total

调用序列是非常的合理的

机器配置是:

[yufeng@wes263 ~]$ cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 23
model name      : Intel(R) Xeon(R) CPU           E5450  @ 3.00GHz
stepping        : 10
cpu MHz         : 1998.000
cache size      : 6144 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm
bogomips        : 5988.98
clflush size    : 64
cache_alignment : 64
address sizes   : 38 bits physical, 48 bits virtual
power management:

8个核心。

1分钟 erlang发起了getuid()系统调个数 ecug的8核心机器 222,100,000 × 8个核心 = 1700M 合每秒30M个系统调用

结论是:如果合理安排的话 erlang的性能是非常高的 同时可以利用到erlang的smp的巨大优势。

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , , ,

研究Erlang 4000小时以后

August 25th, 2009 9 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 研究Erlang 4000小时以后

历经2年半,花了4000小时以后,对erlang的研究有了很大的进步,从原来的兴趣, 到现在的随意的crack, 调优,改进, 指导erlang程序架构的设计,中间经历了很多。

从一个有20年历史的网络程序身上我学到很多,包括高级服务器程序的架构,调度公平性,网络事件处理, 内存管理, 锁管理, SMP管理, 平台移植, 虚拟机,语言的基本构件,用户交互,调试, 诊断, 调优,工具。 也学会了使用OS提供的工具如systemtap, oprofile,内存, CPU工具来诊断,来定位问题,这个可以参考rhel的调优白皮书。

这个成熟系统带来的经验感受如同你窥视一台精密设计的机器,一环套着一环。看似小小的系统,里面凝聚着多少片论文,多少方法改进,顺着Erlang的演化历史,你也随着成长,其中的快乐是无法抗拒的,从中学到的东西绝不是一个库或者一个小程序能够带给你的。从中你会体会到一个大型系统是如何变成一个活生生的系统,实现者如何妥协,如何稳健的持续的改进。每一个Roadmap都值得期待。

感谢erlang的开发小组给我们带来这么好的东西,研究还将继续。。。

距离上次写这篇blog的时候半年又过去了,Erlang代码已经看了3遍了。。。

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags:

系统标准库的hipe支持(高级)

August 23rd, 2009 2 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 系统标准库的hipe支持(高级)

前篇文章http://mryufeng.javaeye.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][/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][/source] [64-bit] [rq:1] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.2  (abort with ^G)
1&gt;

这个也可以通过修改 alias erl=erl -smp disable 以便欺骗编译器生成单cpu模式的beam
去绕过去

2. 动态编译, 等系统运行起来以后,动态把相关的模块编译一遍,这个思路看起来最简单。

我做了个原型 证明这样是可行的。。。

# cat hi.erl
-module(hi).
-export([do/0]).

do()-&gt;
[ turn(M, P)|| {M, P} &lt;-code:all_loaded(), P=/=preloaded].

turn(M, P) -&gt;
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)) -&gt;[{K, tr(V)}] ++ Acc ; (Skip, Acc) -&gt; Acc ++ [Skip] end, [], COpts),
c:c(P1, COpts1 ++ [native, "{hipe, [o3]}"]).

tr(P)-&gt;
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) -&gt;
case get_compile_info(L, options) of
{ok,Val} -&gt; Val;
error -&gt; []
end.

get_compile_info(L, Tag) -&gt;
case lists:keysearch(compile, 1, L) of
{value, {compile, I}} -&gt;
case lists:keysearch(Tag, 1, I) of
{value, {Tag, Val}} -&gt; {ok,Val};
false -&gt; error
end;
false -&gt; error
end.
#erl -nostick
Erlang R13B01 (erts-5.7.2) [source][/source][/source] [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.2  (abort with ^G)
1&gt; mnesia:start().  %启动我们的应用程序
ok
2&gt; 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&gt; 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,<span style="color: red;">native,"{hipe, [o3]}"</span>]
Object file: /home/yufeng/otp_src_R13B01/lib/stdlib/src/../ebin/dict.beam

。。。

看到了是用native模式编译的哦。。。

不过编译过程中有几个模块是有点问题, 得改进下。

Post Footer automatically generated by wp-posturl plugin for wordpress.

大家好 我搬家了

August 11th, 2009 3 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 大家好 我搬家了

准备把站点改成独立域名了,会慢慢的从javaeye上过渡过来,各位记得更新书签哦。

旧的网站还可以访问: mryufeng.javaeye.com

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: 杂七杂八 Tags: