Mercurial > hg > octave-avbm
comparison src/data.cc @ 14635:f8d5095fa90d
improve compatibility of tic and toc
* data.cc (Ftic): Attempt to avoid loss of precision.
(Ftoc): If passed a uint64 argument, use it as the start time (in
microseconds).
(Ftic, Ftoc): Update doc string
New tests.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 14 May 2012 16:24:12 -0400 |
parents | 88e67d58b06b |
children | 7d4f87c75dbb |
comparison
equal
deleted
inserted
replaced
14634:7e10eb490b87 | 14635:f8d5095fa90d |
---|---|
5646 static double tic_toc_timestamp = -1.0; | 5646 static double tic_toc_timestamp = -1.0; |
5647 | 5647 |
5648 DEFUN (tic, args, nargout, | 5648 DEFUN (tic, args, nargout, |
5649 "-*- texinfo -*-\n\ | 5649 "-*- texinfo -*-\n\ |
5650 @deftypefn {Built-in Function} {} tic ()\n\ | 5650 @deftypefn {Built-in Function} {} tic ()\n\ |
5651 @deftypefnx {Built-in Function} {@var{id} =} tic ()\n\ | |
5651 @deftypefnx {Built-in Function} {} toc ()\n\ | 5652 @deftypefnx {Built-in Function} {} toc ()\n\ |
5653 @deftypefnx {Built-in Function} {} toc (@var{id})\n\ | |
5654 @deftypefnx {Built-in Function} {@var{val} =} toc (@dots{})\n\ | |
5652 Set or check a wall-clock timer. Calling @code{tic} without an\n\ | 5655 Set or check a wall-clock timer. Calling @code{tic} without an\n\ |
5653 output argument sets the timer. Subsequent calls to @code{toc}\n\ | 5656 output argument sets the internal timer state. Subsequent calls\n\ |
5654 return the number of seconds since the timer was set. For example,\n\ | 5657 to @code{toc} return the number of seconds since the timer was set.\n\ |
5658 For example,\n\ | |
5655 \n\ | 5659 \n\ |
5656 @example\n\ | 5660 @example\n\ |
5657 @group\n\ | 5661 @group\n\ |
5658 tic ();\n\ | 5662 tic ();\n\ |
5659 # many computations later@dots{}\n\ | 5663 # many computations later@dots{}\n\ |
5663 \n\ | 5667 \n\ |
5664 @noindent\n\ | 5668 @noindent\n\ |
5665 will set the variable @code{elapsed_time} to the number of seconds since\n\ | 5669 will set the variable @code{elapsed_time} to the number of seconds since\n\ |
5666 the most recent call to the function @code{tic}.\n\ | 5670 the most recent call to the function @code{tic}.\n\ |
5667 \n\ | 5671 \n\ |
5668 If called with one output argument then this function returns a scalar\n\ | 5672 If called with one output argument, @code{tic} returns a scalar\n\ |
5669 of type @code{uint64} and the wall-clock timer is not started.\n\ | 5673 of type @code{uint64} that may be later passed to @code{toc}.\n\ |
5670 \n\ | 5674 \n\ |
5671 @example\n\ | 5675 @example\n\ |
5672 @group\n\ | 5676 @group\n\ |
5673 t = tic; sleep (5); (double (tic ()) - double (t)) * 1e-6\n\ | 5677 id = tic; sleep (5); toc (id)\n\ |
5674 @result{} 5\n\ | 5678 @result{} 5.0010\n\ |
5675 @end group\n\ | 5679 @end group\n\ |
5676 @end example\n\ | 5680 @end example\n\ |
5677 \n\ | 5681 \n\ |
5678 Nested timing with @code{tic} and @code{toc} is not supported.\n\ | 5682 Calling @code{tic} and @code{toc} this way allows nested timing calls.\n\ |
5679 Therefore @code{toc} will always return the elapsed time from the most\n\ | |
5680 recent call to @code{tic}.\n\ | |
5681 \n\ | 5683 \n\ |
5682 If you are more interested in the CPU time that your process used, you\n\ | 5684 If you are more interested in the CPU time that your process used, you\n\ |
5683 should use the @code{cputime} function instead. The @code{tic} and\n\ | 5685 should use the @code{cputime} function instead. The @code{tic} and\n\ |
5684 @code{toc} functions report the actual wall clock time that elapsed\n\ | 5686 @code{toc} functions report the actual wall clock time that elapsed\n\ |
5685 between the calls. This may include time spent processing other jobs or\n\ | 5687 between the calls. This may include time spent processing other jobs or\n\ |
5686 doing nothing at all. For example:\n\ | 5688 doing nothing at all.\n\ |
5687 \n\ | |
5688 @example\n\ | |
5689 @group\n\ | |
5690 tic (); sleep (5); toc ()\n\ | |
5691 @result{} 5\n\ | |
5692 t = cputime (); sleep (5); cputime () - t\n\ | |
5693 @result{} 0\n\ | |
5694 @end group\n\ | |
5695 @end example\n\ | |
5696 \n\ | |
5697 @noindent\n\ | |
5698 (This example also illustrates that the CPU timer may have a fairly\n\ | |
5699 coarse resolution.)\n\ | |
5700 @end deftypefn") | 5689 @end deftypefn") |
5701 { | 5690 { |
5702 octave_value retval; | 5691 octave_value retval; |
5703 | 5692 |
5704 int nargin = args.length (); | 5693 int nargin = args.length (); |
5709 octave_time now; | 5698 octave_time now; |
5710 | 5699 |
5711 double tmp = now.double_value (); | 5700 double tmp = now.double_value (); |
5712 | 5701 |
5713 if (nargout > 0) | 5702 if (nargout > 0) |
5714 retval = static_cast<octave_uint64> (1e6 * tmp); | 5703 { |
5704 double ip = 0.0; | |
5705 double frac = modf (tmp, &ip); | |
5706 uint64_t microsecs = static_cast<uint64_t> (CLOCKS_PER_SEC * frac); | |
5707 microsecs += CLOCKS_PER_SEC * static_cast<uint64_t> (ip); | |
5708 retval = octave_uint64 (microsecs); | |
5709 } | |
5715 else | 5710 else |
5716 tic_toc_timestamp = tmp; | 5711 tic_toc_timestamp = tmp; |
5717 | 5712 |
5718 return retval; | 5713 return retval; |
5719 } | 5714 } |
5720 | 5715 |
5721 DEFUN (toc, args, nargout, | 5716 DEFUN (toc, args, nargout, |
5722 "-*- texinfo -*-\n\ | 5717 "-*- texinfo -*-\n\ |
5723 @deftypefn {Built-in Function} {} toc ()\n\ | 5718 @deftypefn {Built-in Function} {} toc ()\n\ |
5719 @deftypefnx {Built-in Function} {} toc (@var{id})\n\ | |
5720 @deftypefnx {Built-in Function} {@var{val} = } toc (@dots{})\n\ | |
5724 See tic.\n\ | 5721 See tic.\n\ |
5725 @end deftypefn") | 5722 @end deftypefn") |
5726 { | 5723 { |
5727 octave_value retval; | 5724 octave_value retval; |
5728 | 5725 |
5729 int nargin = args.length (); | 5726 int nargin = args.length (); |
5730 | 5727 |
5731 if (nargin != 0) | 5728 double start_time = tic_toc_timestamp; |
5732 warning ("tic: ignoring extra arguments"); | 5729 |
5733 | 5730 if (nargin > 1) |
5734 if (tic_toc_timestamp < 0) | 5731 print_usage (); |
5735 { | |
5736 warning ("toc called before timer set"); | |
5737 if (nargout > 0) | |
5738 retval = Matrix (); | |
5739 } | |
5740 else | 5732 else |
5741 { | 5733 { |
5742 octave_time now; | 5734 if (nargin == 1) |
5743 | 5735 { |
5744 double tmp = now.double_value () - tic_toc_timestamp; | 5736 octave_uint64 id = args(0).uint64_scalar_value (); |
5745 | 5737 |
5746 if (nargout > 0) | 5738 if (! error_state) |
5747 retval = tmp; | 5739 { |
5748 else | 5740 uint64_t val = id.value (); |
5749 octave_stdout << "Elapsed time is " << tmp << " seconds.\n"; | 5741 |
5742 start_time | |
5743 = (static_cast<double> (val / CLOCKS_PER_SEC) | |
5744 + static_cast<double> (val % CLOCKS_PER_SEC) / CLOCKS_PER_SEC); | |
5745 | |
5746 // FIXME -- should we also check to see whether the start | |
5747 // time is after the beginning of this Octave session? | |
5748 } | |
5749 else | |
5750 error ("toc: invalid ID"); | |
5751 } | |
5752 | |
5753 if (! error_state) | |
5754 { | |
5755 if (start_time < 0) | |
5756 error ("toc called before timer set"); | |
5757 else | |
5758 { | |
5759 octave_time now; | |
5760 | |
5761 double tmp = now.double_value () - start_time; | |
5762 | |
5763 if (nargout > 0) | |
5764 retval = tmp; | |
5765 else | |
5766 octave_stdout << "Elapsed time is " << tmp << " seconds.\n"; | |
5767 } | |
5768 } | |
5750 } | 5769 } |
5751 | 5770 |
5752 return retval; | 5771 return retval; |
5753 } | 5772 } |
5773 | |
5774 /* | |
5775 %!shared id | |
5776 %! id = tic (); | |
5777 %!assert (isa (id, "uint64")); | |
5778 %!assert (isa (toc (id), "double")); | |
5779 */ | |
5754 | 5780 |
5755 DEFUN (cputime, args, , | 5781 DEFUN (cputime, args, , |
5756 "-*- texinfo -*-\n\ | 5782 "-*- texinfo -*-\n\ |
5757 @deftypefn {Built-in Function} {[@var{total}, @var{user}, @var{system}] =} cputime ();\n\ | 5783 @deftypefn {Built-in Function} {[@var{total}, @var{user}, @var{system}] =} cputime ();\n\ |
5758 Return the CPU time used by your Octave session. The first output is\n\ | 5784 Return the CPU time used by your Octave session. The first output is\n\ |