caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Jun Inoue <jun.lambda@gmail.com>
To: Gabriel Scherer <gabriel.scherer@gmail.com>
Cc: Timothy Bourke <Timothy.Bourke@inria.fr>,
	OCaml list <caml-list@inria.fr>,
	 Marc Pouzet <Marc.Pouzet@ens.fr>
Subject: Re: [Caml-list] Sundials/ML 2.5.0
Date: Fri, 28 Nov 2014 22:05:50 +0100	[thread overview]
Message-ID: <CA+ZA8QwLO23yV181HF8X+53H1wfUoLQEufOwVwvT=c-QWU18QQ@mail.gmail.com> (raw)
In-Reply-To: <CAPFanBE0yP46oDvufBH3XoiTuybLytxJ5LeSzpQyV6vbXaNPag@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4077 bytes --]

Thank you for sharing this interesting information, Gabriel!  We
benchmarked the code exclusively with 4.01.0 and didn't know about the
performance boost in printf.

I just measured the performance with
examples/kinsol/serial/kinFerTron_dns.ml, which was one of the
examples that had the most pronounced effect.  As you suggest, the
numbers are a lot closer with 4.02.1.  The median wall-clock times of
10 runs were:

printf,  OCaml 4.02.1: 1.76[s]
print_*, OCaml 4.02.1: 1.62[s]
printf,  OCaml 4.01.0: 2.04[s]
print_*, OCaml 4.01.0: 1.70[s]

The overhead of using printf is about 8% in 4.02.1, as opposed to
about 20% in 4.01.0.  So in 4.02 the effect is noticeably smaller,
though not unmeasurable.  We should note this in the doc in a future
release.

FYI, the experiment can be reproduced as follows (in bash syntax),
using the attached patch (referred to as
/tmp/kinFerTron_dns_printf.diff below):

# Start at the root of the source tree.
opam switch 4.02.1; eval `opam config env`
./configure && make clean all
cd examples/kinsol/serial
# Measure without modification.
make PERF_DATA_POINTS=10 kinFerTron_dns.opt.perf
../../utils/crunchperf -m kinFerTron_dns.opt.perf >
no-printf-4.02.1-kinFerTron_dns.opt.perf
# Apply patch and measure again.
patch -p4 < /tmp/kinFerTron_dns_printf.diff
make PERF_DATA_POINTS=10 kinFerTron_dns.opt.perf
../../utils/crunchperf -m kinFerTron_dns.opt.perf >
printf-4.02.1-kinFerTron_dns.opt.perf
# Undo changes.
patch -p4 -R < /tmp/kinFerTron_dns_printf.diff

cd ../../..
# Back at the root of the source tree.
opam switch 4.01.0; eval `opam config env`
# (Basically the same thing as above)
./configure && make clean all
cd examples/kinsol/serial
make PERF_DATA_POINTS=10 kinFerTron_dns.opt.perf
../../utils/crunchperf -m kinFerTron_dns.opt.perf >
no-printf-4.01.0-kinFerTron_dns.opt.perf
patch -p4 < /tmp/kinFerTron_dns_printf.diff
make PERF_DATA_POINTS=10 kinFerTron_dns.opt.perf
../../utils/crunchperf -m kinFerTron_dns.opt.perf >
printf-4.01.0-kinFerTron_dns.opt.perf

# Summarize results
for i in *kinFerTron_dns.opt.perf; do printf "\n[$i]\n";
../../utils/crunchperf -s $i; done

On Fri, Nov 28, 2014 at 6:44 PM, Gabriel Scherer
<gabriel.scherer@gmail.com> wrote:
> Thanks for the significant effort put in documenting the bindings
> (and, of course, the cool software and research); your "information
> and documentation" page is impressive.
>
> The page has a very interesting performance comparison of numeric code
> partly or fully written in OCaml (using bigarrays of floats) -- and
> the not-so-surprising results is that the run times of the OCaml
> programs are between 100% and 200% of the run time of the reference C
> implementation.
>
> ( http://inria-parkas.github.io/sundialsml/perf.opt.png )
>
> I'm curious about this specific part of the explanation:
>
>> For instance, some OCaml versions spend a significant fraction of their time
>> in printf, and we were able to lower their ratios by instead using print_string and print_int.
>
> The new 4.02 implementation of formats, due to Benoît Vaugon, should
> be significantly faster (in my experience they match the performance of the
> less-readable print_* sequence in most situations). Did you try those
> OCaml versions with 4.02?
>
> On Fri, Nov 28, 2014 at 2:39 PM, Timothy Bourke <Timothy.Bourke@inria.fr> wrote:
>> We are pleased to announce Sundials/ML, an OCaml interface to the
>> Sundials suite of numerical solvers (CVODE, CVODES, IDA, IDAS, KINSOL).
>>
>> Information and documentation: http://inria-parkas.github.io/sundialsml/
>> Source code (BSD):             https://github.com/inria-parkas/sundialsml
>>
>> opam install sundialsml # (requires Sundials 2.5.0)
>>
>> We gratefully acknowledge the original authors of Sundials, and the
>> support of the ITEA 3 project 11004 MODRIO (Model driven physical
>> systems operation), Inria, and the Departement d'Informatique de l'ENS.
>>
>> Timothy Bourke, Jun Inoue, and Marc Pouzet.
>>



-- 
Jun Inoue

[-- Attachment #2: kinFerTron_dns_printf.diff --]
[-- Type: text/plain, Size: 3091 bytes --]

diff --git a/examples/kinsol/serial/kinFerTron_dns.ml b/examples/kinsol/serial/kinFerTron_dns.ml
index 525cffc..edf4bb8 100644
--- a/examples/kinsol/serial/kinFerTron_dns.ml
+++ b/examples/kinsol/serial/kinFerTron_dns.ml
@@ -115,21 +115,13 @@ let set_initial_guess2 udata =
 
 (* Print first lines of output (problem description) *)
 let print_header fnormtol scsteptol =
-  print_string "\nFerraris and Tronconi test problem\n";
-  print_string "Tolerance parameters:\n";
+  printf "\nFerraris and Tronconi test problem\n";
+  printf "Tolerance parameters:\n";
   printf "  fnormtol  = %10.6g\n  scsteptol = %10.6g\n" fnormtol scsteptol
 
 (* Print solution *)
 let print_output u = printf " %8.6g  %8.6g\n" u.{0} u.{1}
 
-let print_string_5d s i =
-  print_string s;
-  if i < 10 then print_string "    "
-  else if i < 100 then print_string "   "
-  else if i < 1000 then print_string "  "
-  else if i < 10000 then print_string " ";
-  print_int i
-
 (* Print final statistics contained in iopt *)
 (* For high NUM_REPS, the cost of OCaml printf becomes important! *)
 let print_final_stats kmem =
@@ -137,21 +129,20 @@ let print_final_stats kmem =
   let nfe  = Kinsol.get_num_func_evals kmem in
   let nje  = Kinsol.Dls.get_num_jac_evals kmem in
   let nfeD = Kinsol.Dls.get_num_func_evals kmem in
-  print_string "Final Statistics:\n";
-  print_string_5d "  nni = " nni;
-  print_string_5d "    nfe  = " nfe;
-  print_string_5d " \n  nje = " nje;
-  print_string_5d "    nfeD = " nfeD;
-  print_string " \n"
+  printf "Final Statistics:\n";
+  printf "  nni = %5d    nfe  = %5d \n" nni nfe;
+  printf "  nje = %5d    nfeD = %5d \n" nje nfeD
 
 (* MAIN PROGRAM *)
 let solve_it kmem u s glstr mset =
   print_newline ();
-  print_string (if mset==1 then "Exact Newton" else "Modified Newton");
-  if not glstr then print_newline () else print_string " with line search\n";
+  if mset == 1 then printf "Exact Newton"
+  else printf "Modified Newton";
+  if not glstr then printf "\n"
+  else printf " with line search\n";
   Kinsol.set_max_setup_calls kmem mset;
   ignore (Kinsol.solve kmem u glstr s s);
-  print_string "Solution:\n  [x1,x2] = ";
+  printf "Solution:\n  [x1,x2] = ";
   print_output (Nvector.unwrap u);
   print_final_stats kmem
 
@@ -193,9 +184,9 @@ let main () =
 
   (* --------------------------- *)
 
-  print_string "\n------------------------------------------\n";
-  print_string "\nInitial guess on lower bounds\n";
-  print_string "  [x1,x2] = ";
+  printf "\n------------------------------------------\n";
+  printf "\nInitial guess on lower bounds\n";
+  printf "  [x1,x2] = ";
   print_output u1;
 
   RealArray.blit u1 u;
@@ -218,9 +209,9 @@ let main () =
 
   (* --------------------------- *)
 
-  print_string "\n------------------------------------------\n";
-  print_string "\nInitial guess in middle of feasible region\n";
-  print_string "  [x1,x2] = ";
+  printf "\n------------------------------------------\n";
+  printf "\nInitial guess in middle of feasible region\n";
+  printf "  [x1,x2] = ";
   print_output u2;
 
   RealArray.blit u2 u;

  reply	other threads:[~2014-11-28 21:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-28 13:39 Timothy Bourke
2014-11-28 17:44 ` Gabriel Scherer
2014-11-28 21:05   ` Jun Inoue [this message]
2014-11-28 22:20     ` Jun Inoue

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CA+ZA8QwLO23yV181HF8X+53H1wfUoLQEufOwVwvT=c-QWU18QQ@mail.gmail.com' \
    --to=jun.lambda@gmail.com \
    --cc=Marc.Pouzet@ens.fr \
    --cc=Timothy.Bourke@inria.fr \
    --cc=caml-list@inria.fr \
    --cc=gabriel.scherer@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).