<div dir="ltr"><font face="courier new, monospace">Hello Niean,<br></font><div style><font face="courier new, monospace">Mentioned below are few of my suggestions:</font></div><div style><font face="courier new, monospace">1) Disable Nagle in server.</font></div>
<div style><font face="courier new, monospace">2) Try to use {active, once} in server. {active, true} setting may overflow your TCP buffer. In between, how much have you set the TCP read-write buffer (both in OS and application)?</font></div>
<div style><font face="courier new, monospace">3) Not sure what you are trying to achieve with port_command. Its not clear to me..</font></div><div style><font face="courier new, monospace"><br></font></div><div style><font face="courier new, monospace">Other design related suggestions would be to:</font></div>
<div style><font face="courier new, monospace">1) Use async communication model using prim_inets as the listener.</font></div><div style><font face="courier new, monospace">2) Better to use an FSM for managing socket states and flow control.</font></div>
<div style><font face="courier new, monospace"><br></font></div><div style><font face="courier new, monospace">Thanks,</font></div><div style><font face="courier new, monospace">Arun</font></div></div><div class="gmail_extra">
<br clear="all"><div>-Arun</div>
<br><br><div class="gmail_quote">On Mon, May 20, 2013 at 8:00 PM, 聂安 <span dir="ltr"><<a href="mailto:nieanan3602@163.com" target="_blank">nieanan3602@163.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="line-height:1.7;font-size:14px;font-family:arial"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;line-height:normal">hi all,<div>I have a question about the high cpu usage when sending and receiving data via erlang-socket. </div>
<div>My program uses a C/S mode. First, the server start a listening socket, and then the client connect to the server by using gen_tcp:connect. When establishing a connection, the client will keep sending "info" package to the server while waiting for a response from the client ; the server  will respond an "info_ack" to the client when receiving a "info" package.  When there's one client, at most 20000 packages per second are sent betweent C/S, while cpu usage reaches about 90%. My package is very little, at most 10Bytes, so my netcard is idle. When doing the same thing by C language, the cpu usage is just 6% while my netcard turns busy with about 500000 packa
 ges per second. <br></div><div>I have no idea why erlang gets so cpu-consuming.  My program goes as follows:</div><div><br></div><div>Server</div><div>config items about socket setting:</div><div>{tcp_listen_opts, [<span><font color="#00ff00" size="4">binary,{packet,0},{reuseaddr,<u></u>true},{exit_on_close,true},{<u></u>active,false}<u></u><u></u></font></span>]}<br>
</div><div><br></div><div><div> 30 start_connection(Parent, Sock, SockTransform) -></div><div> 31     process_flag(trap_exit, true),</div><div> 32     Name =</div><div> 33     case catch ?NET:connection_string(Sock, inbound) of</div>
<div> 34     {ok, Str}        -> Str;</div><div> 35     {error, enotcon} -> ?NET:fast_close(Sock),exit(<u></u>normal);<u></u></div><div> 36     {error, _Reason} -> ?NET:fast_clost(Sock),exit(<u></u>normal)<u></u></div>
<div> 37     end,</div><div>
  38     Msg = io_lib:format("accept connection ~p(~p)", [Name, self()]),</div><div> 39     ?DEBUG(Msg), log:log(notice, ?MODULE, Msg),</div><div> 40     ClientSock = socket_op(Sock, SockTransform),</div><div> 41     ClientSock = Sock,</div>
<div> 42     {PHost, PPort, Host, Port} =</div><div> 43         socket_op(Sock, fun(S)->?NET:socket_ends(S,<u></u>inbound) end),<u></u></div><div> 44     State = #state{</div><div> 45         parent          = Parent,</div>
<div> 46         sock            = ClientSock,</div><div> 47         name            = list_to_binary(Name),</div><div> 48         callback        = undefined,</div><div> 49        
  host            = Host,</div><div> 50         port            = Port,</div><div> 51         peer_host       = PHost,</div><div> 52         peer_port       = PPort</div><div> 53     },</div><div> 54     try</div><div> 55         %ok = inet_op(),</div>
<div> 56         inet:setopts(ClientSock, [<font color="#00ff00" size="4">{active, true}</font>]),</div><div> 57         Ret = rcv_loop(State),</div><div> 58         WMsg=lists:flatten(io_lib:<u></u>format("closing connection ~p(~p), "<u></u></div>
<div> 59             "reason: ~p", [Name,self(),Ret])),</div><div> 60         ?DEBUG(WMsg), log:log(warning, ?MODULE, WMsg)</div><div>&nbs
 p;61     catch</div><div> 62     E:R -></div><div> 63         EMsg=lists:flatten(io_lib:<u></u>format("closing connection ~p(~p), "<u></u></div><div> 64             "reason: ~p:~p", [Name, self(), E, R])),</div>
<div> 65         ?DEBUG(EMsg), log:log(error, ?MODULE, EMsg)</div><div> 66     after</div><div><div> 66     after</div><div> 67         ?NET:fast_close(ClientSock),</div><div> 68         Msg2=lists:flatten(io_lib:<u></u>format("connection ~p(~p) closed",<u></u></div>
<div> 69             [Name, self()])),</div><div> 70         ?DEBUG(Msg2), log:log(notice, ?MODULE, Msg2)</div><div> 71     end,</div><div> 72     normal.</div><div> 73 </div><div> 74 rcv_loop(#state{sock=Sock}=<u></u>Sta
 te) -><u></u></div><div> 75     receive</div><div> 76     {tcp, Sock, Binary} -></div><div> 77         NState = report_run(State, Binary),% calls port_command to send ack pkg</div><div> 78         %inet:setopts(Sock, [{active, once}]),</div>
<div> 79         rcv_loop(NState);</div><div> 80     {tcp_closed, Sock}  -> 'peer closed';</div><div> 81     _Other              -> rcv_loop(State)</div><div> 82     after ?RCV_TIMEOUT  -> 'rcv timeout'</div>
<div> 83     end.</div></div><div><br></div></div><div><br></div><div><br></div><div>Client</div><div><div> 10 -define(TCP_OPTIONS, <font color="#00ff00">[binary, {packet,0}, {active, false},</font></div><div><font color="#00ff00"> 11                   &nb
 sp;   {exit_on_close,true}, {reuseaddr,true}]</font>).</div></div><div><div>101 setup_short_connection(Host, Port, #state{id=Id}=State) -></div><div>102     case gen_tcp:connect(Host, Port, ?TCP_OPTIONS) of</div><div>
103     {ok, Socket}    -></div><div>104         ?DEBUG("client(~p) connected to ~p:~p", [Id,Host,Port]),</div><div>105         inet:setopts(Socket, [<font color="#00ff00">{active, once}</font>]),</div><div>106         send_request_and_wait_for_<u></u>response(State#state{socket=<u></u>Socket});<u></u><u></u></div>
<div>107     {error, Reason} -></div><div>108         EMsg=lists:flatten(io_lib:<u></u>format("client(~p) connect failed,"<u></u></div><div>109             "reason: ~p", [Id, Reason])),</div><div>110         ?DEBUG(EMsg),</div>
<div>111         {error, 'connect 
 failed'}</div><div>112     end.</div><div><div>118 send_request_and_wait_for_<u></u>response(#state{id=Id,requ_<u></u>cnt=RequCnt}=State) -><u></u><u></u></div><div>119     try</div><div>120         Ref = RequCnt,</div>
<div>121         NState  = send_request(State, Ref),</div><div>122         wait_for_response(NState, Ref)</div><div>123     catch</div><div>124     E:R -></div><div>125         EMsg = io:format("client(~p) failed in send_request_and_wait_for_<u></u>response"<u></u></div>
<div>126             ", reason: ~p:~p", [Id, E, R]),</div><div>127         ?DEBUG(EMsg),</div><div>128         {error, 'error during send or wait'}</div><div>129     end.</div><div>130 </div><div>131 send_request(#state{socket=<u></u>Sock,requ_cnt=RequCnt}=State, Ref) -><u></u></div>
<div>132
      Data = {{"business", "aos"}, {"ref", Ref}},</div><div>133     Pkg  = {{"type", "key"}, {"data", Data}},</div><div>134     JPkg = term_to_binary(Pkg),</div>
<div>135     true = erlang:port_command(Sock, JPkg, [nosuspend]),</div><div>136     State#state{requ_cnt=RequCnt-<u></u>1}.<u></u></div><div>137 </div><div>138 wait_for_response(#state{<u></u>socket=Sock}=State, Ref) -><u></u></div>
<div>139     receive</div><div>140     {tcp, Sock, Binary} -></div><div>141         ok = inet:setopts(Sock, [<font color="#00ff00" size="4">{active,once}</font>]),</div><div>142         case report_run(State, Binary, Ref) of</div>
<div>143         {response, NState} -> send_request_and_wait_for_<u></u>response(NState);<u></u></div><div>144         {other, _}         -> wait_for_response(State, Ref)</div><div>145
          end;</div><div>146     _Other      -> wait_for_response(State, Ref)</div><div>147     after 30000 -> {error, 'rcv response timeout'}</div><div>148     end.</div></div><div><br></div></div><div><br>
</div><div>I'm sorry for my poor English. I will be very grateful if someone help me to solve this problem.</div><div><br></div><div style="text-align:right">yours</div><div style="text-align:right">niean</div></span></div>
<br><br><span title="neteasefooter"><span></span></span><br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br></div>