R14A实现了EEP31,添加了binary模块
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: R14A实现了EEP31,添加了binary模块
Erlang的binary数据结构非常强大,而且偏向底层,在作网络程序的时候,很方便的能够和二进制协议对应起来。但是由于这个数据结构加入erlang语言的时间不是很长,相关的配套模块不是很多。 在binary的匹配,替换,修改就显的非常麻烦。 于是有了EEP31 。 R14A昨天已经实现了这个功能, 在stdlib下添加了个binary模块。 这个模块大部分功能是由BIF实现的, 同时充分考虑了CPU使用的公平性,源码大部分在erl_bif_binary.c下。 还添加了个gurad函数: binary_part进一步方便我们写匹配条件。
我们在源码里面发现了以下注释:
/*
* The native implementation functions for the module binary.
* Searching is implemented using aither Boyer-More or Aho-Corasick
* depending on number of searchstrings (BM if one, AC if more than one).
* Native implementation is mostly for efficiency, nothing
* (except binary:referenced_byte_size) really *needs* to be implemented
* in native code.
*/
这个模块兼顾了效率和方便性,使用起来就大大简化了代码的复杂度,有福气了。
Post Footer automatically generated by wp-posturl plugin for wordpress.
R14A添加新指令优化Ref消息的接收
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: R14A添加新指令优化Ref消息的接收
Erlang的惯用法之一就是在消息匹配的时候,如果需要唯一性,通常会通过make_ref搞个唯一的Ref来作为消息的一部分来匹配。这个惯用法用在gen_server:call或者demonitor这样的使用频度很高的函数里面。由于erlang的消息匹配是再消息队列里面挨个遍历来匹配,特别是消息队列特别长的时候,会有很大的性能瓶颈。于是新的优化出现了,以下是编译器beam_receive.erl里面的解释,写的很清楚:
%%%
%%% In code such as:
%%%
%%% Ref = make_ref(), %Or erlang:monitor(process, Pid)
%%% .
%%% .
%%% .
%%% receive
%%% {Ref,Reply} -> Reply
%%% end.
%%%
%%% we know that none of the messages that exist in the message queue
%%% before the call to make_ref/0 can be matched out in the receive
%%% statement. Therefore we can avoid going through the entire message
%%% queue if we introduce two new instructions (here written as
%%% BIFs in pseudo-Erlang):
%%%
%%% recv_mark(SomeUniqInteger),
%%% Ref = make_ref(),
%%% .
%%% .
%%% .
%%% recv_set(SomeUniqInteger),
%%% receive
%%% {Ref,Reply} -> Reply
%%% end.
%%%
%%% The recv_mark/1 instruction will save the current position and
%%% SomeUniqInteger in the process context. The recv_set
%%% instruction will verify that SomeUniqInteger is still stored
%%% in the process context. If it is, it will set the current pointer
%%% for the message queue (the next message to be read out) to the
%%% position that was saved by recv_mark/1.
%%%
%%% The remove_message instruction must be modified toinvalidate
%%% the information stored by the previous recv_mark/1, in case there
%%% is another receive executed between the calls to recv_mark/1 and
%%% recv_set/1.
%%%
%%% We use a reference to a label (i.e. a position in the loaded code)
%%% as the SomeUniqInteger.
%%%
结论: 点滴优化成就高性能。
Post Footer automatically generated by wp-posturl plugin for wordpress.
非阻塞connect的一个细节
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: 非阻塞connect的一个细节
昨天听zhuzhaoyuan说的一个connect细节. 通常我们connect的时候都是非阻塞的, 在connect调用后把句柄挂到poll去, 等poll通知可写的时候, 我们就认为connect成功了. 但是在linux平台下实际上不一定成功, 具体的要用socket get_opt来检查下出错码来决定.
以下是从man 2 connnect摘抄的:
EINPROGRESS
The socket(2,7,n) is non-blocking and the connection cannot be com-
pleted immediately. It is possible to select(2,7,2 select_tut)(2) or poll(2) for
completion by selecting the socket(2,7,n) for writing. After select(2,7,2 select_tut)
indicates writability, use getsockopt(2) to read(2,n,1 builtins) the SO_ERROR
option at level SOL_SOCKET to determine whether connect com-
pleted successfully (SO_ERROR is zero) or unsuccessfully
(SO_ERROR is one of the usual error(8,n) codes listed here, explain-
ing the reason for the failure).
我们看下erlang的inet_drv是如何处理的.
./erts/emulator/drivers/common/inet_drv.c:
{
int error = 0; /* Has to be initiated, we check it */
unsigned int sz = sizeof(error); /* even if we get -1 */
int code = sock_getopt(desc->inet.s, SOL_SOCKET, SO_ERROR,
(void *)&error, &sz);
if ((code < 0) || error) {
desc->inet.state = TCP_STATE_BOUND; /* restore state */
ret = async_error(INETP(desc), error);
goto done;
}
}
结论: 细节决定品质.
Post Footer automatically generated by wp-posturl plugin for wordpress.
中国地图(俺去过的地方)
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: 中国地图(俺去过的地方)
持续更新!
Post Footer automatically generated by wp-posturl plugin for wordpress.
How to Build a Debug Enabled Erlang RunTime System
原创文章,转载请注明: 转载自系统技术非业余研究
很多朋友在问如何调试Erlang的驱动代码等等,其实otp源码下的INSTALL.md写的很清楚, 摘抄下:
How to Build a Debug Enabled Erlang RunTime System
————————————————–
After completing all the normal building steps described above a debug
enabled runtime system can be built. To do this you have to change
directory to `$ERL_TOP/erts/emulator`.
注:一定要注意这句话, 假设你现在在otp源码目录下,正常编译好了, export ERL_TOP=`pwd` 然后进入erts/emulator目录下
In this directory execute:
$ make debug FLAVOR=$FLAVOR
where `$FLAVOR` is either `plain` or `smp`. The flavor options will
produce a beam.debug and beam.smp.debug executable respectively. The
files are installed along side with the normal (opt) versions `beam.smp`
and `beam`.
To start the debug enabled runtime system execute:
$ $ERL_TOP/bin/cerl -debug
The debug enabled runtime system features lock violation checking,
assert checking and various sanity checks to help a developer ensure
correctness. Some of these features can be enabled on a normal beam
using appropriate configure options.
There are other types of runtime systems that can be built as well
using the similar steps just described.
$ make $TYPE FLAVOR=$FLAVOR
where `$TYPE` is `opt`, `gcov`, `gprof`, `debug`, `valgrind`, or `lcnt`.
These different beam types are useful for debugging and profiling
purposes.
祝玩的开心!
Post Footer automatically generated by wp-posturl plugin for wordpress.
erts_modified_timings是如何起作用的
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: erts_modified_timings是如何起作用的
我们先看下man erl
+T Level:
Enables modified timing and sets the modified timing level. Currently valid range is 0-9. The timing of the runtime system will
change. A high level usually means a greater change than a low level. Changing the timing can be very useful for finding timing
related bugs.Currently, modified timing affects the following:
Process spawning:
A process calling spawn, spawn_link, spawn_monitor, or spawn_opt will be scheduled out immediately after completing the
call. When higher modified timing levels are used, the caller will also sleep for a while after being scheduled out.Context reductions:
The amount of reductions a process is a allowed to use before being scheduled out is increased or reduced.Input reductions:
The amount of reductions performed before checking I/O is increased or reduced.NOTE: Performance will suffer when modified timing is enabled. This flag is only intended for testing and debugging. Also note
that return_to and return_from trace messages will be lost when tracing on the spawn BIFs. This flag may be removed or changed
at any time without prior notice.
我们可以知道这个选项是用于修改VM的进程和IO调度的时间,以及延迟spawn的执行时间, 使得和时间相关的问题,容易得到暴露,达到发现问题的目的。 但是Level是如何对于参数的呢?下面这个表格能回答问题了.
erts/emulator/beam/erl_init.c
132ErtsModifiedTimings erts_modified_timings[] = {
133 /* 0 */ {make_small(0), CONTEXT_REDS, INPUT_REDUCTIONS},
134 /* 1 */ {make_small(0), 2*CONTEXT_REDS, 2*INPUT_REDUCTIONS},
135 /* 2 */ {make_small(0), CONTEXT_REDS/2, INPUT_REDUCTIONS/2},
136 /* 3 */ {make_small(0), 3*CONTEXT_REDS, 3*INPUT_REDUCTIONS},
137 /* 4 */ {make_small(0), CONTEXT_REDS/3, 3*INPUT_REDUCTIONS},
138 /* 5 */ {make_small(0), 4*CONTEXT_REDS, INPUT_REDUCTIONS/2},
139 /* 6 */ {make_small(1), CONTEXT_REDS/4, 2*INPUT_REDUCTIONS},
140 /* 7 */ {make_small(1), 5*CONTEXT_REDS, INPUT_REDUCTIONS/3},
141 /* 8 */ {make_small(10), CONTEXT_REDS/5, 3*INPUT_REDUCTIONS},
142 /* 9 */ {make_small(10), 6*CONTEXT_REDS, INPUT_REDUCTIONS/4}
143};
注意延时是以毫秒为单位的。
比如说: erl +T 8 那么spawn延时10ms, IO处理时间加大到3倍, 有利于快速处理IO事件。
Post Footer automatically generated by wp-posturl plugin for wordpress.
erts_ use_sender_punish未公开的特性
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: erts_ use_sender_punish未公开的特性
我们知道erlang的VM调度是根据reds的,每个进程初始的时候分配2000个reds, 一旦这个reds用完了,进程就被挂起,放到队列去排队,等待下一次调度。OTP R13B04下一个进程给另外一个进程发送消息,是需要扣除发送者一定的reds, 这样看起来更公平。因为古语说杀敌一千, 自损八百。 但是Erlang有个未公开的选项来避开这种情况:erl +snsp
我们来看代码:
emulator/beam/erl_init.c
1131 else if (sys_strcmp("nsp", sub_param) == 0)
1132 erts_use_sender_punish = 0;
emulator/beam/bif.c
/* send to local process */
erts_send_message(p, rp, &rp_locks, msg, 0);
if (!erts_use_sender_punish)
res = 0;
else {
#ifdef ERTS_SMP
res = rp->msg_inq.len*4;
if (ERTS_PROC_LOCK_MAIN & rp_locks)
res += rp->msg.len*4;
#else
res = rp->msg.len*4;
#endif
}
正常情况下 扣除的reds是 接收者队列长度的4倍。
结论: 我们如果需要批量发送的场合,可以使用这个选项。
Post Footer automatically generated by wp-posturl plugin for wordpress.
Recent Comments