How large is each packet? Can multiple packets fit into one TCP window? Have you looked at the TCP/IP wire-level data with Wireshark/Ethereal to see if the packets are being combined at the TCP level? If you see that you are only getting one packet per TCP frame (assuming a packet is much smaller than the window size), you might be falling foul of the Nagle congestion algorithm. The fact that manually buffering your packets improves performance suggests this may be the case. Nagle says that send, send, send is OK, receive, receive, receive is ok, and even send, receive, send, receive is ok, but you get into trouble if sends and receives are mixed asymmetrically on the same socket (e.g. send, send, receive).<br>
<br>Also, I don't understand your transmit_loop. Where is it looping (or am I misunderstanding something)?<br><br>From what I have seen, people writing Erlang TCP/IP code do an {active, once} receive, and when getting the first packet, drop into another loop that does a passive receive until there's no data waiting, then go back into the {active, once} receive. Are you doing this? I am not sure, but I fear that if all your receives are {active, once} it will incur more CPU overhead than the active/passive split. It's hard to know because I can't see enough of your code to know what you are doing overall. Disclaimer: I'm no Erlang or TCP/IP expert.<br>
<br>Hope this helps.<br><br><div class="gmail_quote">2008/6/19 Rapsey <<a href="mailto:rapsey@gmail.com">rapsey@gmail.com</a>>:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I have a streaming server written in Erlang. When it was pushing 200-300 mb/s the CPU was getting completely hammered. I traced the problem to gen_tcp:send. <br>So instead of sending every audio/video packet with a single gen_tcp:send call, I buffer 3 packets and then send them all at once. CPU consumption dropped dramatically.<br>

On one of the servers I have a simple proxy, the main process that sends packets between the client and some other server looks like this:<br><br>transmit_loop({tcp, Sock, Data}, P) when P#transdat.client == Sock -><br>

    gen_tcp:send(P#transdat.server, Data),<br>    inet:setopts(P#transdat.client, [{active, once}]),<br>    {ok, P};<br>transmit_loop({tcp, Sock, Data}, P) when P#transdat.server == Sock -><br>    gen_tcp:send(P#transdat.client, Data),<br>

    inet:setopts(P#transdat.server, [{active, once}]),<br>    {ok, P};<br>transmit_loop({start, ServerPort}, P) -><br>    {ok, Sock} = gen_tcp:connect("<a href="http://127.0.0.1" target="_blank">127.0.0.1</a>", ServerPort, [binary, {active, once}, {packet, 0}]),<br>

    {ok, P#transdat{server = Sock}};<br>transmit_loop({tcp_closed, _}, _) -><br>    exit(stop).<br><br>The proxy is eating more CPU time than the streaming server.<br>Is this normal behavior? The server is running  OSX 10.4<br>

<br><br>Sergej<br>
<br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://www.erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://www.erlang.org/mailman/listinfo/erlang-questions</a><br></blockquote></div><br>