David,<br><br>Thanks for trying out the benchmark.<br><br>With my limited knowledge of TCP/IP, I believe you are seeing the 300,000 limit because TCP/IP requires acknowledgements to each packet, and although it can batch up multiple acknowledgements in one packet, there is a theoretical limit of packets per seconds beyond which it cannot go due to the laws of physics. I understand that limit is determined by the Round-Trip Time (RTT), which can be shown by ping. On my system, pinging <a href="http://127.0.0.1">127.0.0.1</a> gives a minimum RTT of 0.018 ms (out of 16 pings). That means that the maximum number of packets that can make it to and dest and back per second is 1/0.000018 seconds, or 55555 packets per second. The TCP/IP stack is evidently packing 5 or 6 blocks into each packet to get the 300K blocks/sec you are seeing. Using Wireshark or Ethereal would confirm this. I am guessing that this means that the TCP window is about 6 * 1000 bytes or 6KB.<br>
<br>What I neglected to tell this group is that I have modified the Linux sysctl.conf as follows, which might have had an effect (like I said, I am not an expert):<br><br># increase Linux autotuning TCP buffer limits<br># min, default, and max number of bytes to use<br>
# set max to at least 4MB, or higher if you use very high BDP paths<br>net.ipv4.tcp_rmem = 4096 87380 16777216 <br>net.ipv4.tcp_wmem = 4096 32768 16777216<br><br>When I have more time, I will vary a number of different Erlang TCP/IP parameters and get a data set together that gives a broader picture of the effect of the parameters.<br>
<br>Thanks again for taking the time.<br><br><div class="gmail_quote">2008/6/24 David Mercer <<a href="mailto:dmercer@gmail.com">dmercer@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;">
<div link="blue" vlink="blue" lang="EN-US">
<div>
<p><span style="color: navy;">I tried some alternative block
sizes (using the blksize option). I found that from 1 to somewhere
around––maybe a bit short of––1000 bytes, the test was
able to send about 300,000 blocks in 10 seconds regardless of size. (That
means, 0.03 MB/sec for block size of 1, 0.3 MB/sec for block size of 10, 3
MB/sec for block size of 100, etc.) I suspect the system was CPU bound at
those levels.</span></p>
<p><span style="color: navy;"> </span></p>
<p><span style="color: navy;">Above 1000, the number of blocks
sent seemed to decrease, though this was more than offset by the increased size
of the blocks. Above about 10,000 byte blocks (may have been less, I didn't
check any value between 4,000 and 10,000), however, performance peaked and
block size no longer mattered: it always sent between 70 and 80 MB/sec. My
machine is clearly slower than Edwin's…</span></p>
<p><span style="color: navy;"> </span></p>
<p><span style="color: navy;">DBM</span></p>
<p><span style="color: navy;"> </span></p>
<div style="border-style: none none none solid; border-color: -moz-use-text-color -moz-use-text-color -moz-use-text-color blue; border-width: medium medium medium 1.5pt; padding: 0in 0in 0in 4pt;">
<div>
<div style="text-align: center;" align="center">
<hr align="center" size="2" width="100%">
</div>
<p><b><span style="font-family: Tahoma;">From:</span></b><span style="font-family: Tahoma;"> <a href="mailto:erlang-questions-bounces@erlang.org" target="_blank">erlang-questions-bounces@erlang.org</a>
[mailto:<a href="mailto:erlang-questions-bounces@erlang.org" target="_blank">erlang-questions-bounces@erlang.org</a>] <b>On Behalf Of </b>Rapsey<br>
<b>Sent:</b> Tuesday, June 24, 2008 14:01<br>
<b>To:</b> <a href="mailto:erlang-questions@erlang.org" target="_blank">erlang-questions@erlang.org</a><br>
<b>Subject:</b> Re: [erlang-questions] why is gen_tcp:send slow?</span></p>
</div><div><div></div><div class="Wj3C7c">
<p> </p>
<p style="margin-bottom: 12pt;">You're using very large
packets. I think the results would be much more telling if the packets would be
a few kB at most. That is closer to most real life situations. <br>
<br>
<br>
Sergej</p>
<div>
<p>On Tue, Jun 24, 2008 at 8:43 PM, Edwin Fine <<a href="mailto:erlang-questions_efine@usa.net" target="_blank">erlang-questions_efine@usa.net</a>>
wrote:</p>
<p style="margin-bottom: 12pt;">I wrote a small benchmark in
Erlang to see how fast I could get socket communications to go. All the
benchmark does is pump the same buffer to a socket for (by default) 10 seconds.
It uses {active, once} each time, just like you do. <br>
<br>
Server TCP options:<br>
{active, once},<br>
{reuseaddr, true},<br>
{packet, 0},<br>
{packet_size, 65536},<br>
{recbuf, 1000000}<br>
<br>
Client TCP options:<br>
{packet, raw},<br>
{packet_size, 65536},<br>
{sndbuf, 1024 * 1024},<br>
{send_timeout, 3000}<br>
<br>
Here are some results using Erlang R12B-3 (erl +K true in the Linux version):<br>
<br>
Linux (Ubuntu 8.10 x86_64, Intel Core 2 Q6600, 8 GB):<br>
- Using localhost (<a href="http://127.0.0.1" target="_blank">127.0.0.1</a>):
7474.14 MB in 10.01 secs (746.66 MB/sec)<br>
- Using 192.168.x.x IP address: 8064.94 MB in 10.00 secs (806.22 MB/sec) [Don't
ask me why it's faster than using loopback, I repeated the tests and got the
same result]<br>
<br>
Windows XP SP3 (32 bits), Intel Core 2 Duo E6600:<br>
- Using loopback: 2166.97 MB in 10.02 secs (216.35 MB/sec)<br>
- Using 192.168.x.x IP address: 2140.72 MB in 10.02 secs (213.75 MB/sec)<br>
- On Gigabit Ethernet to the Q6600 Linux box: 1063.61 MB in 10.02 secs (106.17
MB/sec) using non-jumbo frames. I don't think my router supports jumbo frames.<br>
<br>
There's undoubtedly a huge discrepancy between the two systems, whether because
of kernel poll in Linux, or that it's 64 bits, or unoptimized Windows TCP/IP
flags, I don't know. I don't believe it's the number of CPUs (there's only 1
process sending and one receiving), or the CPU speed (they are both 2.4 GHz
Core 2s).<br>
<br>
Maybe some Erlang TCP/IP gurus could comment.<br>
<br>
I've attached the code for interest. It's not supposed to be production
quality, so please don't beat me up :) although I am always open to suggestions
for improvement. If you do improve it, I'd like to see what you've done. Maybe
there is another simple Erlang tcp benchmark program out there (i.e. not
Tsung), but I couldn't find one in a cursory Google search.<br>
<br>
To run:<br>
<br>
VM1:<br>
<br>
tb_server:start(Port, Opts).<br>
tb_server:stop() to stop.<br>
<br>
Port = integer()<br>
Opts = []|[opt()]<br>
opt() = {atom(), term()} (Accepts inet setopts options, too)<br>
<br>
The server prints out the transfer rate (for simplicity).<br>
<br>
VM2:<br>
tb_client(Host, Port, Opts).<br>
<br>
Host = atom()|string() hostname or IP address<br>
Port, Opts as in tb_server<br>
<br>
Runs for 10 seconds, sending a 64K buffer as fast as possible to Host/Port.<br>
You can change this to 20 seconds (e.g.) by adding the tupls {time_limit,
20000} to Opts.<br>
You can change buffer size by adding the tuple {blksize, Bytes} to Opts.</p>
<div>
<p>2008/6/20 Rapsey <<a href="mailto:rapsey@gmail.com" target="_blank">rapsey@gmail.com</a>>:</p>
<div>
<div>
<p>All data goes through nginx which acts as a proxy. Its CPU
consumption is never over 1%.<br>
<br>
<br>
Sergej</p>
<div>
<div>
<p style="margin-bottom: 12pt;"> </p>
<div>
<p>On Thu, Jun 19, 2008 at 9:35 PM, Javier París Fernández <<a href="mailto:javierparis@udc.es" target="_blank">javierparis@udc.es</a>>
wrote:</p>
<p><br>
El 19/06/2008, a las 20:06, Rapsey escribió:</p>
<div>
<blockquote style="border-style: none none none solid; border-color: -moz-use-text-color -moz-use-text-color -moz-use-text-color rgb(204, 204, 204); border-width: medium medium medium 1pt; padding: 0in 0in 0in 6pt; margin-left: 4.8pt; margin-right: 0in;">
<p style="margin-bottom: 12pt;"> </p>
<p>It loops from another module, that way I can update the code
at any time without disrupting anything.<br>
The packets are generally a few hundred bytes big, except keyframes which tend
to be in the kB range. I haven't tried looking with wireshark. Still it
seems a bit odd that a large CPU consumption would be the symptom. The traffic
is strictly one way. Either someone is sending the stream or receiving it.<br>
The transmit could of course be written with a passive receive, but the code
would be significantly uglier. I'm sure someone here knows if setting {active,
once} every packet is CPU intensive or not.<br>
It seems the workings of gen_tcp is quite platform dependent. If I run the code
in windows, sending more than 128 bytes per gen_tcp call significantly
decreases network output.<br>
Oh and I forgot to mention I use R12B-3.</p>
</blockquote>
<p> </p>
</div>
<p>Hi,<br>
<br>
Without being an expert.<br>
<br>
200-300 mb/s in small (hundreds of bytes) packets means a *lot* of system
calls if you are doing a gen_tcp:send for each one. If you buffer 3 packets,
you are reducing that by a factor of 3 :). I'd try to do an small test doing
the same thing in C and compare the results. I think it will also eat a lot of
CPU.<br>
<br>
About the proxy CPU... I'm a bit lost about it, but speculating wildly it is
possible that the time spent doing the system calls that gen_tcp is doing is
added to the proxy CPU process.<br>
<br>
Regards.</p>
</div>
<p> </p>
</div>
</div>
<p> </p>
</div>
</div>
<div>
<p>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org" target="_blank">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></p>
</div>
</div>
<p> </p>
</div>
<p> </p>
</div></div></div>
</div>
</div>
<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>