Re: [Nethttpd-plex] Poor performance on FreeBSD 8.2

Matías Giovannini <[email protected]> Mon, 4 Jul 2011 19:50:26 -0300
Newsgroups gmane.comp.lang.ocaml.lib.net.devel
Message-ID <CALzEXo_N4i6c85apdta1Bm-remtdqOdECpCemyxbNVS9cT83vw@mail.gmail.com>
After a little ktrace'ing, I've found the following puzzling sequence of
events. Nethttpd receives the request, processes it, sends the headers, the
response, and finishes with "0\r\n\r\n". It gets ready to accept the next
request, *after 100 ms of wait in poll*:

 74420 xbi_mock 1309817486.450514 CALL  gettimeofday(0x7fffffffde70,0)
 74420 xbi_mock 1309817486.450518 RET   gettimeofday 0
 74420 xbi_mock 1309817486.450521 CALL  poll(0x80195a180,0x1,0x1770)
 74420 xbi_mock 1309817486.450524 RET   poll 1
 74420 xbi_mock 1309817486.450527 CALL
 recvfrom(0x5,0x7fffffff9e30,0x2000,0,0,0)
 74420 xbi_mock 1309817486.450530 RET   recvfrom -1 errno 35 Resource
temporarily unavailable
 74420 xbi_mock 1309817486.450552 CALL  gettimeofday(0x7fffffffde90,0)
 74420 xbi_mock 1309817486.450557 RET   gettimeofday 0
 *74420 xbi_mock 1309817486.450560 CALL  poll(0x80195a180,0x1,0x1770)*
* 74420 xbi_mock 1309817486.550412 RET   poll 1*
* *74420 xbi_mock 1309817486.550424 CALL
 recvfrom(0x5,0x7fffffff9e50,0x2000,0,0,0)
 74420 xbi_mock 1309817486.550430 GIO   fd 5 read 644 bytes

I have omitted the not very interesting sequence of events leading to this;
note that the socket is FD 5. The first poll returns immediately but
recvfrom(FD=5) fails with EWOULDBLOCK; the second poll is tried with what
seems 100 ms delay, and the next recvfrom eventually succeeds.

These 100ms neatly account for my ~10 req/s throughput.

The full ktrace log file is available upon request. Regards,
Matías.


On Mon, Jul 4, 2011 at 6:13 PM, Matías Giovannini <[email protected]>wrote:

> Stéphane,
>
> Thank you for your reply. I miscopied the configuration. That was a test I
> made to see if semaphores were having an impact on throughput, which I found
> they didn't. The FreeBSD kernel has the sem module compiled in.
>
> I'll try to test the bytecode version to see if there's any difference.
>
> The final configuration from an unmodified 3.3.3 tarball is:
>
> Welcome to Ocamlnet version 3.3.3
> Checking operating system... FreeBSD
>
> *** Note that you might need to load the 'sem' kernel
> *** module to make semaphores work: kldload sem
>
> Checking for findlib... found
> Checking multi-threading support... posix (ok)
> Checking word size... 64 bit
> Checking endianess... little
> Checking for GPROF... found
> Checking for PCRE... found
> Checking whether Ocaml has Printexc.register_printer... found
> Checking whether Ocaml has fancy page tables... found
> Checking for POSIX shared memory... found
> Checking for POSIX semaphores... found
> Checking for POSIX fadvise... not found
> Checking for POSIX fallocate... not found
> Checking for POSIX memalign... found
> Checking for POSIX pthread... found
> Checking for syslog... found
> Checking for POSIX functions like openat... found
> Checking for fchdir... found
> Checking for fdopendir... found
> Checking for GPROF... found
> Checking for win32... no
> Checking for camlzip... found
>
> Effective options:
>     -enable-pcre
>     -disable-gtk
>     -disable-gtk2
>     -disable-tcl
>     -disable-ssl
>     -enable-zip
>     -disable-crypto
>     -disable-apache
>     -with-nethttpd
>     -without-rpc-auth-dh
>     -bindir /usr/local/bin
>     -datadir /usr/local/lib/ocaml/site-lib/netstring
>
> Writing Makefile.conf
>
> Please check Makefile.conf.
>
> The test harness is an OCaml-cURL script:
>
> let xml = "<?xml version='1.0' encoding='utf-8'?>\r\n\
> <soapenv:Envelope xmlns:soapenv=\"
> http://schemas.xmlsoap.org/soap/envelope/\"\
> ><soapenv:Body\
> ></soapenv:Body\
> ></soapenv:Envelope>" (* '"' *)
>
> let make_post url =
> let curl = new Curl.handle in
>  curl#set_writefunction String.length; (* ignore result *)
> curl#set_verbose false;
>  curl#set_post true;
> curl#set_httpheader [
> "Content-Type: text/xml; charset=\"UTF-8\"";
>  "SOAPAction: \"\"";
> ];
> curl#set_postfields xml;
>  curl#set_postfieldsize (String.length xml);
> curl#set_url url;
> curl
>
> let make_get url =
> let curl = new Curl.handle in
> curl#set_writefunction String.length; (* ignore result *)
>  curl#set_verbose false;
> curl#set_post false;
> curl#set_url url;
>  curl
>
> let run_test ?(verbose=false) count curl =
> let n_ok = ref 0
>  and time = ref 0. in
> let lap = Unix.gettimeofday () in
> for i = 1 to count do
>  curl#perform;
> if curl#get_httpcode = 200 then incr n_ok;
> time := !time +. curl#get_totaltime
>  done;
> let lap = Unix.gettimeofday () -. lap in
> if verbose then Printf.printf "Total time: %.3f s (%.2f req/s)\ncURL  time:
> %.3f s (%.2f req/s)\nsuccesses: %d/%d\n"
>  lap (float count /. lap)
> !time (float count /. !time)
> !n_ok count
>
> let main () =
> let verbose  = ref false
> and count    = ref 100
>  and method_  = ref make_post
> and url      = ref None in
> let set_url s = match !url with
>  | None  -> url := Some s
> | Some _ -> raise (Arg.Bad "URL already specified")
>  in
> let set_method s = match s with
> | "p" | "post" -> method_ := make_post
>  | "g" | "get"  -> method_ := make_get
> | _ -> assert false
>  in
> let usage = "usage: " ^ (Filename.basename Sys.executable_name) ^ "
> [options] <url>" in
>  let opt_list = Arg.align [
> "-m", Arg.Symbol (["g";"get";"p";"post"], set_method), "  Method (default
> \"post\")";
> "-n", Arg.Set_int count,                Printf.sprintf "  Test count
> (default %d)"  !count;
> "-v", Arg.Set     verbose,                             "  Verbose output";
>  ] in
> Arg.parse opt_list set_url usage;
> try
>  let url = match !url with
> | None   -> raise (Arg.Bad "Must specify URL")
>  | Some s -> s
> and verbose = !verbose in
> Curl.global_init Curl.CURLINIT_GLOBALALL;
>  let curl = !method_ url in
> run_test ~verbose !count curl;
> curl#cleanup;
>  Curl.global_cleanup ();
> exit 0
> with Sys_error msg  -> prerr_endline msg; exit 1
>  | Arg.Bad msg       -> prerr_endline msg; exit 2
> | Curl.CurlException (Curl.CURLE_COULDNT_CONNECT, _, _) ->
>  Printf.eprintf "Can't connect to host\n";
> exit 1
> | Curl.CurlException (_, code, message) ->
>  Printf.eprintf "cURL error %d: %s\n" code message;
> exit 1
> | e -> prerr_endline ("Unexpected error: " ^ Printexc.to_string e); exit 1
>
> let () = main ()
>
>
> On Mon, Jul 4, 2011 at 5:56 PM, Stéphane Legrand <[email protected]> wrote:
>
>> Hello,
>>
>> I did the following tests on my configuration :
>>
>>  FreeBSD 8.2-STABLE
>>  Intel Celeron D CPU 3.33GHz (32 bits)
>>  1 GB
>>
>>
>> - Native netplex with output in gnome terminal, 127.0.0.1 :
>>
>> siege -c 1 -t 60S -b 'http://127.0.0.1:4444/'
>>
>> Transactions:                  14752 hits
>> Availability:                 100.00 %
>> Elapsed time:                  59.13 secs
>> Data transferred:              31.40 MB
>> Response time:                  0.00 secs
>> Transaction rate:             249.47 trans/sec
>> Throughput:                     0.53 MB/sec
>> Concurrency:                    0.78
>> Successful transactions:       14752
>> Failed transactions:               0
>> Longest transaction:            0.15
>> Shortest transaction:           0.00
>>
>>
>> - Native netplex with output in gnome terminal, localhost :
>>
>> siege -c 1 -t 60S -b 'http://localhost:4444/'
>>
>> Transactions:                  10554 hits
>> Availability:                 100.00 %
>> Elapsed time:                  59.67 secs
>> Data transferred:              22.47 MB
>> Response time:                  0.00 secs
>> Transaction rate:             176.87 trans/sec
>> Throughput:                     0.38 MB/sec
>> Concurrency:                    0.85
>> Successful transactions:       10554
>> Failed transactions:               0
>> Longest transaction:            0.09
>> Shortest transaction:           0.00
>>
>>
>> - Bytecode netplex with output in gnome terminal, 127.0.0.1 :
>>
>> siege -c 1 -t 60S -b 'http://127.0.0.1:4444/'
>>
>> Transactions:                   6343 hits
>> Availability:                 100.00 %
>> Elapsed time:                  59.72 secs
>> Data transferred:              13.50 MB
>> Response time:                  0.01 secs
>> Transaction rate:             106.21 trans/sec
>> Throughput:                     0.23 MB/sec
>> Concurrency:                    0.99
>> Successful transactions:        6343
>> Failed transactions:               0
>> Longest transaction:            0.15
>> Shortest transaction:           0.00
>>
>>
>> - Bytecode netplex with output in gnome terminal, localhost :
>>
>> siege -c 1 -t 60S -b 'http://localhost:4444/'
>>
>> Transactions:                   6204 hits
>> Availability:                 100.00 %
>> Elapsed time:                  59.56 secs
>> Data transferred:              13.21 MB
>> Response time:                  0.01 secs
>> Transaction rate:             104.16 trans/sec
>> Throughput:                     0.22 MB/sec
>> Concurrency:                    0.99
>> Successful transactions:        6204
>> Failed transactions:               0
>> Longest transaction:            0.14
>> Shortest transaction:           0.00
>>
>>
>> As you can see, the minimum is 104 req/sec. Can you please specify your
>> test where you get 10 req/sec ? If i can, i will try to run it on my
>> computer.
>>
>> And here is my output of configure. POSIX semaphores are found, i do
>> have the sem kernel module loaded before to run configure. I don't know
>> if it could explain the slowness you see ?
>>
>>
>> Welcome to Ocamlnet version 3.3.3
>> Checking operating system... FreeBSD
>>
>> *** Note that you might need to load the 'sem' kernel
>> *** module to make semaphores work: kldload sem
>>
>> Checking for findlib... found
>> Checking multi-threading support... posix (ok)
>> Checking word size... 32 bit
>> Checking endianess... little
>> Checking for GPROF... found
>> Checking for PCRE... found
>> Checking whether Ocaml has Printexc.register_printer... found
>> Checking whether Ocaml has fancy page tables... found
>> Checking for POSIX shared memory... found
>> Checking for POSIX semaphores... found
>> Checking for POSIX fadvise... not found
>> Checking for POSIX fallocate... not found
>> Checking for POSIX memalign... found
>> Checking for POSIX pthread... found
>> Checking for syslog... found
>> Checking for POSIX functions like openat... found
>> Checking for fchdir... found
>> Checking for fdopendir... found
>> Checking for GPROF... found
>> Checking for win32... no
>> Checking for cryptokit... found
>>
>>
>>
>> Regards,
>> Stéphane.
>>
>> Le lundi 04 juillet 2011 à 12:16 -0300, Matías Giovannini a écrit :
>> > Hello,
>> >
>> >
>> > I'm stymied about a huge discrepancy in performance for Nethttpd-plex
>> > on FreeBSD 8.2, compared to Mac OS X 10.6.8.
>> >
>> >
>> > Testing with a OCaml-cURL client making purely sequential GET requests
>> > on the loopback interface in a loop against
>> > examples/nethttpd/netplex.ml I get > 900 req/sec on Mac OS X 10.6.8
>> > (MacBook, Intel Core 2 Duo 2.0 GHz, 2 GB RAM) compared to aprox. 10
>> > req/sec on FreeBSD 8.2 (Quad-core amd64, 8 GB RAM).
>> >
>> >
>> > Looking at the configuration results, I tried manually disabled POSIX
>> > semaphores and *at functions on FreeBSD to see if that had any impact,
>> > to no avail.
>> >
>> >
>> > Testing against a very simple HTTP/1.0 "server" that just accepts and
>> > prints a zero-length 200 OK response I get double throughput on
>> > FreeBSD compared to Mac OS X (6800 req/s vs. 3300 req/s), so I can
>> > rule out networking stack differences.
>> >
>> >
>> > I'd really appreciate any guidance on this issue.
>> >
>> >
>> > The output of configure on FreeBSD is as follows:
>> >
>> >
>> > Welcome to Ocamlnet version 3.3.3
>> > Checking operating system... FreeBSD
>> >
>> >
>> > *** Note that you might need to load the 'sem' kernel
>> > *** module to make semaphores work: kldload sem
>> >
>> >
>> > Checking for findlib... found
>> > Checking multi-threading support... posix (ok)
>> > Checking word size... 64 bit
>> > Checking endianess... little
>> > Checking for GPROF... found
>> > Checking for PCRE... found
>> > Checking whether Ocaml has Printexc.register_printer... found
>> > Checking whether Ocaml has fancy page tables... found
>> > Checking for POSIX shared memory... found
>> > Checking for POSIX semaphores... not found
>> > Checking for POSIX fadvise... not found
>> > Checking for POSIX fallocate... not found
>> > Checking for POSIX memalign... found
>> > Checking for POSIX pthread... found
>> > Checking for syslog... found
>> > Checking for POSIX functions like openat... not found (or incomplete)
>> > Checking for fchdir... found
>> > Checking for fdopendir... found
>> > Checking for GPROF... found
>> > Checking for win32... no
>> > Checking for camlzip... found
>> >
>> >
>> > Effective options:
>> >     -enable-pcre
>> >     -disable-gtk
>> >     -disable-gtk2
>> >     -disable-tcl
>> >     -disable-ssl
>> >     -enable-zip
>> >     -disable-crypto
>> >     -disable-apache
>> >     -with-nethttpd
>> >     -without-rpc-auth-dh
>> >     -bindir /usr/local/bin
>> >     -datadir /usr/local/lib/ocaml/site-lib/netstring
>> >
>> >
>> > Writing Makefile.conf
>>
>>
>>
>>
>>
>>
>> ------------------------------------------------------------------------------
>> All of the data generated in your IT infrastructure is seriously valuable.
>> Why? It contains a definitive record of application performance, security
>> threats, fraudulent activity, and more. Splunk takes this data and makes
>> sense of it. IT sense. And common sense.
>> http://p.sf.net/sfu/splunk-d2d-c2
>> _______________________________________________
>> Ocamlnet-devel mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/ocamlnet-devel
>>
>
>

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2

_______________________________________________
Ocamlnet-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ocamlnet-devel