comp.lang.ada
 help / color / mirror / Atom feed
* Re: Simple Real_Time.Time_Span question
  1998-10-13  0:00 Simple Real_Time.Time_Span question dennison
  1998-10-13  0:00 ` Tucker Taft
@ 1998-10-13  0:00 ` David C. Hoos, Sr.
  1998-10-13  0:00   ` dennison
  1998-10-13  0:00 ` dennison
  1998-10-14  0:00 ` dewar
  3 siblings, 1 reply; 21+ messages in thread
From: David C. Hoos, Sr. @ 1998-10-13  0:00 UTC (permalink / raw)



dennison@telepath.com wrote in message <6vvsgo$rvo$1@nnrp1.dejanews.com>...
>I need to convert values of Ada.Real_Time.Time_Span into floating point
>values for use in time-based simulation calculations. I'd think there *has*
>to be a way to do this, but I don't see one. All I see is the ability to do
>it indirectly via a conversion to Duration. But that looses the extra
>accuracy of Time_Span, which was the whole point of using it in the first
>place.
>
>Am I missing something?

Yes, a couple of things, anyway, viz.:

    1.  I think you're talking about precision and not accuracy.

    2.  Since the types involved are defined in the RM as
implementation-dependent, it is implementation-dependent whether there is
any loss of precision going from Ada.Real_Time.Time_Span to Duration.  In
the case of the GNAT compiler, these both have resolution (precision) of one
nanosecond.  In fact, the specification for Ada.Real_Time.Time_Span in GNAT
is new Duration.  What other compilers may do is ....??








^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-13  0:00 Simple Real_Time.Time_Span question dennison
@ 1998-10-13  0:00 ` Tucker Taft
  1998-10-13  0:00 ` David C. Hoos, Sr.
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: Tucker Taft @ 1998-10-13  0:00 UTC (permalink / raw)


dennison@telepath.com wrote:

: I need to convert values of Ada.Real_Time.Time_Span into floating point
: values for use in time-based simulation calculations. I'd think there *has*
: to be a way to do this, but I don't see one. All I see is the ability to do
: it indirectly via a conversion to Duration. But that looses the extra
: accuracy of Time_Span, which was the whole point of using it in the first
: place.

: Am I missing something?

You might try using Split(Time_Of(),...), and then multiplying the 
resulting reduced Time_Span by 1000 before converting it to Duration.  
That should end up preserving more of the accuracy.
You could run the 1000*<reduced Time_Span> back through the
Split(Time_Of()) combo again to get even more accuracy.
E.g.:

    function To_Float(TS : Time_Span) return Float is
        SC1, SC2, SC3 : Seconds_Count;
	TS1, TS2, TS3 : Time_Span;
    begin
	-- Use Split(Time_Of()) to split time span into seconds and fraction
	-- Repeat twice to get microseconds and fraction thereof
	Split(Time_Of(0, TS), SC1, TS1);
	Split(Time_Of(0, TS1*1000), SC2, TS2);
	Split(Time_Of(0, TS2*1000), SC3, TS3);
	    -- NOTE: it is safe to multiply by 1000 because RM95 D.8(31) 
	    -- guarantees that Time_Span'Last is >= 3600 seconds.

	-- Finally do the conversion of the remaining time-span to duration
	-- and add to other pieces.
	return (Float(SC1)*1.0E9 + Float(SC2)*1.0E6 + Float(SC3)*1.0E3
	  + Float(To_Duration(TS3*1000))) / 1.0E9;
    end To_Float;

No comment on how fast the above will run...

: --
: T.E.D.

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA
An AverStar Company




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-13  0:00 Simple Real_Time.Time_Span question dennison
  1998-10-13  0:00 ` Tucker Taft
  1998-10-13  0:00 ` David C. Hoos, Sr.
@ 1998-10-13  0:00 ` dennison
  1998-10-14  0:00 ` dewar
  3 siblings, 0 replies; 21+ messages in thread
From: dennison @ 1998-10-13  0:00 UTC (permalink / raw)


In article <6vvsgo$rvo$1@nnrp1.dejanews.com>,
  dennison@telepath.com wrote:
> I need to convert values of Ada.Real_Time.Time_Span into floating point
> values for use in time-based simulation calculations. I'd think there *has*

Update: Here's what I ended up doing:

   -- Routine to convert a real_time time_span into a float.
   function To_Float ( Span : in Ada.Real_Time.Time_Span ) return Float is

  -- We have to convert to and from Time because its the only way to handle 
-- time spans of more than about 2 seconds or so without getting a constraint
 -- error.  Span_Time : Ada.Real_Time.Time := Ada.Real_Time.Time_Of (SC => 0,
 TS => Span);  Ticks  : Integer;  Subspan  : Ada.Real_Time.Time_Span; 
Seconds  : Ada.Real_Time.Seconds_Count;  begin

      Ada.Real_Time.Split (T  => Span_Time,
                           SC => Seconds,
                           TS => Subspan);

      Ticks := Subspan / Ada.Real_Time.Time_Span_Unit;

      return Float(Seconds) + Float(Ticks * Ada.Real_Time.Time_Unit);
   end To_Float;


I don't much like this solution, as it will blow up in the unlikely event
that there are more Time_Span_Units in a second than Integer'last. Plus it
performs *way* more work than the following code that this vendor *could*
have put in the body of Ada.Real_Time:

   function To_Float ( Span : in Ada.Real_Time.Time_Span ) return Float is
   begin
      return Float(Span.sec) + (Float(Span.msec) * Time_Unit);
   end;

--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-13  0:00 ` David C. Hoos, Sr.
@ 1998-10-13  0:00   ` dennison
  1998-10-14  0:00     ` Niklas Holsti
  1998-10-14  0:00     ` Robert I. Eachus
  0 siblings, 2 replies; 21+ messages in thread
From: dennison @ 1998-10-13  0:00 UTC (permalink / raw)


In article <7003e4$534@hacgate2.hac.com>,
  "David C. Hoos, Sr." <david.c.hoos.sr@ada95.com> wrote:
>
> dennison@telepath.com wrote in message <6vvsgo$rvo$1@nnrp1.dejanews.com>...
> >I need to convert values of Ada.Real_Time.Time_Span into floating point
> >values for use in time-based simulation calculations. I'd think there *has*
> >to be a way to do this, but I don't see one. All I see is the ability to do
> >it indirectly via a conversion to Duration. But that looses the extra
> >accuracy of Time_Span, which was the whole point of using it in the first
> >place.
> >
> >Am I missing something?
>
> Yes, a couple of things, anyway, viz.:
>
>     1.  I think you're talking about precision and not accuracy.
Ok. Fine. "precision".

>     2.  Since the types involved are defined in the RM as
> implementation-dependent, it is implementation-dependent whether there is
> any loss of precision going from Ada.Real_Time.Time_Span to Duration.  In

I didn't miss that at all. That *was my point*. Consider the following:  o 
My vendor didn't bother to document the definition of Duration.  o  This code
is very likely to be ported to other RTOS/Compiler combinations.  o  A
typical real time simulation needs to perform floating-point caculations
based on the elapsed time since the last calculation. I know telemetry
applications also need this. Probably many (most?) other real-time
application domains need this as well.

  Thus a package billed as "Real_Time" ought to provide a portable way to get
a floating point value of a delta time (time_span). Where is it?

--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Simple Real_Time.Time_Span question
@ 1998-10-13  0:00 dennison
  1998-10-13  0:00 ` Tucker Taft
                   ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: dennison @ 1998-10-13  0:00 UTC (permalink / raw)


I need to convert values of Ada.Real_Time.Time_Span into floating point
values for use in time-based simulation calculations. I'd think there *has*
to be a way to do this, but I don't see one. All I see is the ability to do
it indirectly via a conversion to Duration. But that looses the extra
accuracy of Time_Span, which was the whole point of using it in the first
place.

Am I missing something?

--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-14  0:00 ` dewar
@ 1998-10-14  0:00   ` dennison
  1998-10-14  0:00     ` Matthew Heaney
  1998-10-14  0:00     ` Robert I. Eachus
  0 siblings, 2 replies; 21+ messages in thread
From: dennison @ 1998-10-14  0:00 UTC (permalink / raw)


In article <700usk$cht$1@nnrp1.dejanews.com>,
  dewar@gnat.com wrote:

> It is odd for a compiler not to choose a sufficient precision for Duration
> to accurately represent a Time_Span value. Certainly in the case of GNAT,
> Duration is represented in nanoseconds, and you will not lose any precision
> following the conversion path you suggest.

I hate to drag my own thread off topic, but how did you do that? According to
9.6(27) Duration has to represent up to 86,400 seconds. For a "classical"
implementation of a fixed-point type that can represent both 86,400 and
0.000_000_001, my poor calculations tell me you'd need at least 47 bits. On a
32-bit processor that would be tricky.

--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-14  0:00   ` dennison
@ 1998-10-14  0:00     ` Matthew Heaney
  1998-10-14  0:00     ` Robert I. Eachus
  1 sibling, 0 replies; 21+ messages in thread
From: Matthew Heaney @ 1998-10-14  0:00 UTC (permalink / raw)


dennison@telepath.com writes:

> In article <700usk$cht$1@nnrp1.dejanews.com>,
>   dewar@gnat.com wrote:
> 
> > It is odd for a compiler not to choose a sufficient precision for Duration
> > to accurately represent a Time_Span value. Certainly in the case of GNAT,
> > Duration is represented in nanoseconds, and you will not lose any precision
> > following the conversion path you suggest.
> 
> I hate to drag my own thread off topic, but how did you do that? According to
> 9.6(27) Duration has to represent up to 86,400 seconds. For a "classical"
> implementation of a fixed-point type that can represent both 86,400 and
> 0.000_000_001, my poor calculations tell me you'd need at least 47 bits. On a
> 32-bit processor that would be tricky.

GNAT uses 64 bits to implement fixed point types.  One of the reasons
this is nice is that you can have an unsigned, 32 bit fixed point type.










^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-13  0:00   ` dennison
  1998-10-14  0:00     ` Niklas Holsti
@ 1998-10-14  0:00     ` Robert I. Eachus
  1998-10-14  0:00       ` Keith Thompson
  1998-10-14  0:00       ` Jonathan Guthrie
  1 sibling, 2 replies; 21+ messages in thread
From: Robert I. Eachus @ 1998-10-14  0:00 UTC (permalink / raw)


In article <700ic6$q1p$1@nnrp1.dejanews.com> dennison@telepath.com writes:

 >  Thus a package billed as "Real_Time" ought to provide a portable way to get
 > a floating point value of a delta time (time_span). Where is it?

   1) You've got to be kidding!  Converting time to floating point to
do calculations is what caused problems with the Patriot system in
Dahran.

   2) Any fixed point value can be converted to any floating point
type.  The precision and accuracy will be determined by the types
involved.  You seem to be under the impression that (double-precision)
floating point will be more accurate than Duration.  Assuming that
Duration is a 64-bit fixed point type (and the annexes encourage such
an implementation), this will usually not be the case.

   3) What I suggest you do is write a short program to print out the
values of interest, then write and complain.  Actually the program you
need is very trivial:

   with Ada.Text_IO;
   with Ada.Calendar;
   with System;
   with Ada.Real_Time;
   procedure Test_Times is
     use type Ada.Real_Time.Time_Span;
     package Duration_IO is new Ada.Text_IO.Fixed_IO(Duration);
   begin
     Ada.Text_IO.Put(" Duration'Small is ");
     Duration_IO.Put(Duration'Small * 1_000_000,1,5,0);
     Ada.Text_IO.Put_Line(" microseconds.");

     Ada.Text_IO.Put(" System.Tick is ");
     Duration_IO.Put(System.Tick * 1_000,1,5,0);
     Ada.Text_IO.Put_Line(" milliseconds.");

     Ada.Text_IO.Put(" Ada.Real_Time.Time_Unit is ");
     Duration_IO.Put(Duration(Ada.Real_Time.Time_Unit * 1_000_000),1,5,0);
     Ada.Text_IO.Put_Line(" microseconds.");

     Ada.Text_IO.Put(" Ada.Real_Time.Time_Span_Unit is ");
     Duration_IO.Put(Ada.Real_Time.To_Duration
                 (Ada.Real_Time.Time_Span_Unit * 1_000_000),1,5,0);
     Ada.Text_IO.Put_Line(" microseconds.");

     Ada.Text_IO.Put(" Ada.Real_Time.Tick is ");
     Duration_IO.Put(Ada.Real_Time.To_Duration
                 (Ada.Real_Time.Tick * 1_000_000),1,5,0);
     Ada.Text_IO.Put_Line(" microseconds.");

   end Test_Times;

   On spectre, which is a SunOS machine using GNAT 3.10p I get:

spectre% test_times
 Duration'Small is 0.00100 microseconds.
 System.Tick is 1000.00000 milliseconds.
 Ada.Real_Time.Time_Unit is 0.00100 microseconds.
 Ada.Real_Time.Time_Span_Unit is 0.00100 microseconds.
 Ada.Real_Time.Tick is 1.00000 microseconds.

   Obviously you will lose nothing when converting to Duration from
Ada.Real_Time.Time_Span.  Converting from there to any floating point
will have rounding error for most values of type Time_Span.  (Some,
but not all, values of the form K * 2**(-N) will be represented
accurately.)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-14  0:00   ` dennison
  1998-10-14  0:00     ` Matthew Heaney
@ 1998-10-14  0:00     ` Robert I. Eachus
  1998-10-15  0:00       ` dennison
  1 sibling, 1 reply; 21+ messages in thread
From: Robert I. Eachus @ 1998-10-14  0:00 UTC (permalink / raw)


In article <702b25$30a$1@nnrp1.dejanews.com> dennison@telepath.com writes:

  > I hate to drag my own thread off topic, but how did you do that?
  > According to 9.6(27) Duration has to represent up to 86,400
  > seconds. For a "classical" implementation of a fixed-point type
  > that can represent both 86,400 and 0.000_000_001, my poor
  > calculations tell me you'd need at least 47 bits. On a 32-bit
  > processor that would be tricky.

   You use 64-bits, and when necessary, multiprecision arithmetic.
Remember that on many 32-bit processors, addition and subtraction of
64-bit numbers is either supported directly in the instruction set, or
through instructions like add-with-carry.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-14  0:00     ` Robert I. Eachus
  1998-10-14  0:00       ` Keith Thompson
@ 1998-10-14  0:00       ` Jonathan Guthrie
  1998-10-15  0:00         ` dennison
  1 sibling, 1 reply; 21+ messages in thread
From: Jonathan Guthrie @ 1998-10-14  0:00 UTC (permalink / raw)


Robert I. Eachus <eachus@spectre.mitre.org> wrote:
> In article <700ic6$q1p$1@nnrp1.dejanews.com> dennison@telepath.com writes:

>  >  Thus a package billed as "Real_Time" ought to provide a portable way to get
>  > a floating point value of a delta time (time_span). Where is it?

>    1) You've got to be kidding!  Converting time to floating point to
> do calculations is what caused problems with the Patriot system in
> Dahran.

This is not correct or, more correctly, is misleading.  (I'm basing this
reply on the write-up that was in DDJ a year or so after the fact.)

The problem most certainly was NOT the fault of doing time calculations in
floating-point.  The problem was determining the time by adding the
(admittedly floating-point) duration of the timer tick to a "time elapsed
since system start" value.  Since the duration of each timer tick is
subject to round-off error, and since that round-off error is constant,
adding all that stuff up causes that round-off error to accumulate.  
Eventually, that accumulated error becomes significant. That is what
happened during the famous Patriot missile failure.

Of course, the correct approach is either to count integral numbers of
ticks and then find the current time when you want to know it by
multiplying the tick count by the duration of each tick or to make sure
that the units of the time intervals are themselves integral.  If, for
example, you have a 100Hz timer tick, measuring intervals in seconds and
fractions therein is not a good idea, but counting them in milliseconds
works just fine whether you're accumulating floating-point values or
integer.

Note that while using floating-point values to accumulate the time make it
easy to screw up this way, they are neither necessary nor sufficient for
the problem to occur.  You can accumulate integral values in a
floating-point number, or have round-off error with integers.

In the case in question, as long as you don't determine the overall
time span by adding up a series of smaller time_spans, you should be okay.
(You might even be okay if you add up the series, but I don't know Ada
well enough to guarantee it.)

-- 
Jonathan Guthrie (jguthrie@brokersys.com)
Information Broker Systems   +281-895-8101   http://www.brokersys.com/
12703 Veterans Memorial #106, Houston, TX  77014, USA

We sell Internet access and commercial Web space.  We also are general
network consultants in the greater Houston area.





^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-13  0:00   ` dennison
@ 1998-10-14  0:00     ` Niklas Holsti
  1998-10-14  0:00       ` Niklas Holsti
  1998-10-14  0:00     ` Robert I. Eachus
  1 sibling, 1 reply; 21+ messages in thread
From: Niklas Holsti @ 1998-10-14  0:00 UTC (permalink / raw)


dennison@telepath.com wrote:
> 
> I need to convert values of Ada.Real_Time.Time_Span into floating point
> values for use in time-based simulation calculations. I'd think there *has*
> to be a way to do this, but I don't see one. All I see is the ability to do
> it indirectly via a conversion to Duration. But that looses the extra
> accuracy of Time_Span, which was the whole point of using it in the first
> place.

   [ snip ]
> 
>   Thus a package billed as "Real_Time" ought to provide a portable way to get
> a floating point value of a delta time (time_span). Where is it?

How about taking your Time_Span value, dividing it with Time_Span_Unit
to get an integer, then multiplying with Time_Span to get a real number?
The items Time_Span_Unit, "/" and Time_Span are defined in
Ada.Real_Time.

I haven't tried it, but the LRM seems clear on this.

Niklas Holsti




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-14  0:00     ` Niklas Holsti
@ 1998-10-14  0:00       ` Niklas Holsti
  0 siblings, 0 replies; 21+ messages in thread
From: Niklas Holsti @ 1998-10-14  0:00 UTC (permalink / raw)


To correct a typo of mine:
I wrote:
> 
> dennison@telepath.com wrote:
> >
> > I need to convert values of Ada.Real_Time.Time_Span into floating point
> > values for use in time-based simulation calculations. I'd think there *has*
> > to be a way to do this, but I don't see one. All I see is the ability to do
> > it indirectly via a conversion to Duration. But that looses the extra
> > accuracy of Time_Span, which was the whole point of using it in the first
> > place.
> 
>    [ snip ]
> >
> >   Thus a package billed as "Real_Time" ought to provide a portable way to get
> > a floating point value of a delta time (time_span). Where is it?
> 
> How about taking your Time_Span value, dividing it with Time_Span_Unit
> to get an integer, then multiplying with Time_Span to get a real number?
                                           ********* should be Time_Unit
> The items Time_Span_Unit, "/" and Time_Span are defined in
                                    ********* should be Time_Unit
> Ada.Real_Time.
> 
> I haven't tried it, but the LRM seems clear on this.
> 
> Niklas Holsti




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-14  0:00     ` Robert I. Eachus
@ 1998-10-14  0:00       ` Keith Thompson
  1998-10-14  0:00       ` Jonathan Guthrie
  1 sibling, 0 replies; 21+ messages in thread
From: Keith Thompson @ 1998-10-14  0:00 UTC (permalink / raw)


eachus@spectre.mitre.org (Robert I. Eachus) writes:
> In article <700ic6$q1p$1@nnrp1.dejanews.com> dennison@telepath.com writes:
>    1) You've got to be kidding!  Converting time to floating point to
> do calculations is what caused problems with the Patriot system in
> Dahran.

A brief summary: floating-point is tricky.

>    2) Any fixed point value can be converted to any floating point
> type.  The precision and accuracy will be determined by the types
> involved.  You seem to be under the impression that (double-precision)
> floating point will be more accurate than Duration.  Assuming that
> Duration is a 64-bit fixed point type (and the annexes encourage such
> an implementation), this will usually not be the case.

But you can't assume this in portable code.  I'm reasonably certain
that there are existing Ada 95 implementations in which Duration is 32
bits -- and the original poster explicitly said that the code would
have to be ported to other implementations.

-- 
Keith Thompson (The_Other_Keith) kst@cts.com <http://www.ghoti.net/~kst> <*>
Qualcomm, San Diego, California, USA  <http://www.qualcomm.com>
I must be a techno-geek.  My mouse is bigger than my phone.




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-13  0:00 Simple Real_Time.Time_Span question dennison
                   ` (2 preceding siblings ...)
  1998-10-13  0:00 ` dennison
@ 1998-10-14  0:00 ` dewar
  1998-10-14  0:00   ` dennison
  3 siblings, 1 reply; 21+ messages in thread
From: dewar @ 1998-10-14  0:00 UTC (permalink / raw)


In article <6vvsgo$rvo$1@nnrp1.dejanews.com>,
  dennison@telepath.com wrote:
> I need to convert values of Ada.Real_Time.Time_Span into floating point
> values for use in time-based simulation calculations. I'd think there *has*
> to be a way to do this, but I don't see one. All I see is the ability to do
> it indirectly via a conversion to Duration. But that looses the extra
> accuracy of Time_Span, which was the whole point of using it in the first
> place.
>
> Am I missing something?


It is odd for a compiler not to choose a sufficient precision for Duration
to accurately represent a Time_Span value. Certainly in the case of GNAT,
Duration is represented in nanoseconds, and you will not lose any precision
following the conversion path you suggest.

Robert Dewar
Ada Core Technologies

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-14  0:00     ` Robert I. Eachus
@ 1998-10-15  0:00       ` dennison
  1998-10-16  0:00         ` Robert I. Eachus
  0 siblings, 1 reply; 21+ messages in thread
From: dennison @ 1998-10-15  0:00 UTC (permalink / raw)


In article <EACHUS.98Oct14135537@spectre.mitre.org>,
  eachus@spectre.mitre.org (Robert I. Eachus) wrote:
> In article <702b25$30a$1@nnrp1.dejanews.com> dennison@telepath.com writes:
>
>   > that can represent both 86,400 and 0.000_000_001, my poor
>   > calculations tell me you'd need at least 47 bits. On a 32-bit
>   > processor that would be tricky.
>
>    You use 64-bits, and when necessary, multiprecision arithmetic.
> Remember that on many 32-bit processors, addition and subtraction of
> 64-bit numbers is either supported directly in the instruction set, or
> through instructions like add-with-carry.

Hmmm. I guess there's a bit of a hole in my education where multiprecision
integer arithmetic is concerned. I assume an add-with-carry instruction has
some way of handling when *two* bits need to be carried (eg: the msbit of
both previous operands was a 1, and there was a carry-in to that
bit-position). Or perhaps you have to add one to the second word of the
result if there was a carry and the msbit of the first word of the result is
0?

Either way it sounds like simple arithmetic will be significantly slower for
a Duration implemented in this way than one would typically expect of a
predefined type. I can certianly see where compiler vendors for some
real-time platforms might decide *not* to do that. So I don't think I can
safely assume that a Time_Span of a few microseconds will translate well into
Duration on any platform that this code may end up on (or even its current
platform, 'till I find out for sure).

--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-14  0:00       ` Jonathan Guthrie
@ 1998-10-15  0:00         ` dennison
  1998-10-16  0:00           ` Tucker Taft
  1998-10-17  0:00           ` Niklas Holsti
  0 siblings, 2 replies; 21+ messages in thread
From: dennison @ 1998-10-15  0:00 UTC (permalink / raw)


In article <702oll$1v4$1@news.hal-pc.org>,
  Jonathan Guthrie <jguthrie@weck.brokersys.com> wrote:

> Of course, the correct approach is either to count integral numbers of
> ticks and then find the current time when you want to know it by
> multiplying the tick count by the duration of each tick or to make sure
> that the units of the time intervals are themselves integral.  If, for
> example, you have a 100Hz timer tick, measuring intervals in seconds and
> fractions therein is not a good idea, but counting them in milliseconds
> works just fine whether you're accumulating floating-point values or
> integer.

That is pretty much what I ended up doing (see my second post in this thread).
The thing that bugs me about that is the large amount of work it involves,
compared to what could have been done as part of the package (again, see my
previous post).

Even though this code has to be portable, I probably would have considered
cheating and using Duration if I could have found any documentation from my
compiler vendor on how it is implemented. Unfortunately, there seem to be
*no* documentation requirements on Duration (unlike all *other* predefined
types), so my vendor didn't bother to document it. Lucky me.

The silly thing is that near as I can tell this is what the package is
supposed to be there for. Needing to perform calculations based on elapsed
time since the last iteration is part of what makes a real-time system. A
typical R/T program will have a cycle rate of 60Hz or greater (ours is 240Hz,
but may go up to 2KHz). But the numeric type Ada.Real_Time provides for this
purpose (Duration) is only required by the laguage to support increments of
1/50th of a second!

I don't think there is much doubt that the specification of Ada.Real_Time is
seriously broken in this respect. Until this can be addressed properly, I
would implore Ada vendors who support this annex to provide a child package
with subprograms capable of converting between Float and Time_Span. I realize
Float as a type has its problems too, but between Float and Duration I think
we would have the needs of Real-time programs fairly well covered.

--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-15  0:00         ` dennison
@ 1998-10-16  0:00           ` Tucker Taft
  1998-10-16  0:00             ` dennison
  1998-10-17  0:00           ` Niklas Holsti
  1 sibling, 1 reply; 21+ messages in thread
From: Tucker Taft @ 1998-10-16  0:00 UTC (permalink / raw)


dennison@telepath.com wrote:

: ...
: Even though this code has to be portable, I probably would have considered
: cheating and using Duration if I could have found any documentation from my
: compiler vendor on how it is implemented. Unfortunately, there seem to be
: *no* documentation requirements on Duration (unlike all *other* predefined
: types), so my vendor didn't bother to document it. Lucky me.

There should be an "annex M" which contains such information.

But even without it, it is pretty trivial to found out information
about predefined types.  E.g.:

   with Ada.Text_IO; use Ada.Text_IO;
   procedure Tell_Me_About_Duration is
   begin
       Put_Line("Duration'Size = " & Integer'Image(Duration'Size));
       Put_Line("Duration'Small = " & Float'Image(Duration'Small));
       Put_Line("Duration'First = " & Duration'Image(Duration'First));
       Put_Line("Duration'Last = " & Duration'Image(Duration'Last));
   end;

On one of our compilers, this produces the following:

    Duration'Size =  32
    Duration'Small =  6.10352E-05
    Duration'First = -131072.0000
    Duration'Last =  131071.9999

I suspect a number of Ada 95 compilers will produce the same result.

In any case, I sympathize with your goal.
The simplest solution I have heard suggested is the following:

    function To_Float(TS : Time_Span) return Float is
        SC : Seconds_Count;
        Frac : Time_Span;
    begin
        Split(Time_Of(0, TS), SC, Frac);
        return Float(SC) + Time_Unit * Float(Frac/Time_Span_Unit);
    end To_Float;

: --
: T.E.D.

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA
An AverStar Company




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-16  0:00           ` Tucker Taft
@ 1998-10-16  0:00             ` dennison
  1998-10-16  0:00               ` dewar
  0 siblings, 1 reply; 21+ messages in thread
From: dennison @ 1998-10-16  0:00 UTC (permalink / raw)


In article <F0wCFH.In.0.-s@inmet.camb.inmet.com>,
  stt@houdini.camb.inmet.com (Tucker Taft) wrote:
> dennison@telepath.com wrote:
>
> : ...
> : Even though this code has to be portable, I probably would have considered
> : cheating and using Duration if I could have found any documentation from my
> : compiler vendor on how it is implemented. Unfortunately, there seem to be
> : *no* documentation requirements on Duration (unlike all *other* predefined
> : types), so my vendor didn't bother to document it. Lucky me.
>
> There should be an "annex M" which contains such information.
>

Yes, there is an annex M. No, it does not contain that information. It has
entries for the predefined integer types declared in Standard (13), and the
predefined floating-point types declared in Standard (17), but none for the
predefined fixed-point types declared in Standard. As far as I can tell from
the LRM's annex M, there are *no* documentation requirements for Duration.
I'd be happy to be proven wrong (cuz then I could go bitch at my vendor).

--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-15  0:00       ` dennison
@ 1998-10-16  0:00         ` Robert I. Eachus
  0 siblings, 0 replies; 21+ messages in thread
From: Robert I. Eachus @ 1998-10-16  0:00 UTC (permalink / raw)


In article <705g81$g9s$1@nnrp1.dejanews.com> dennison@telepath.com writes:

  > Hmmm. I guess there's a bit of a hole in my education where
  > multiprecision integer arithmetic is concerned. I assume an
  > add-with-carry instruction has some way of handling when *two*
  > bits need to be carried (eg: the msbit of both previous operands
  > was a 1, and there was a carry-in to that bit-position). Or
  > perhaps you have to add one to the second word of the result if
  > there was a carry and the msbit of the first word of the result is
  > 0?

  You are losing me a bit here, but I think I can answer your
question.  Let's assume a 32-bit machine (with 32-bit registers) where
we want to add two 64-bit numbers.  Let's be specific and use the
680x0 family.  Assume that the quantity in the register pair D0,D1 is
to be added to the quantity in the register pair D2,D3:

   ADD.L D1,D3
   ADDX  D0,D2

   The ADDX instruction adds the carry bit to the source and
destination, and puts the result in the destination register.  For the
case of a double length add, that is all there is to it.  After the
ADDX, all the condition code values are what you would want.  The Z
bit is only set if the entire result is zero, the N bit is set if the
quantity as a whole is negative, etc.  If you want to do a series of
such adds, then you do something like:

   ADD.L D2,D5
   ADDX  D1,D4
   ADDX  D0,D3

   And so on.  In any case, there is only one possible carry bit, just
as you can only carry a value between 0 and 9 when adding decimal
numbers by hand.

 > Either way it sounds like simple arithmetic will be significantly
 > slower for a Duration implemented in this way than one would
 > typically expect of a predefined type. I can certianly see where
 > compiler vendors for some real-time platforms might decide *not* to
 > do that. So I don't think I can safely assume that a Time_Span of a
 > few microseconds will translate well into Duration on any platform
 > that this code may end up on (or even its platform, 'till I find
 > out for sure).

   You are confused. I left out register loading code above, any
required overflow checking, etc.  From experience, adding or
subtracting 64-bit integer quantities on a 32-bit register machine is
less than 20 percent slower at most than the same algorithm using
32-bit quantities.  Multiplication by small factors, expecially if
constant, doesn't affect these results, but any use of division can
and will have a large impact.

   Since arithmetic as a part of time-keeping is almost all addition
and subtraction, this means that a 64-bit Duration type will have an
almost negligible impact on code speed.  (Remember, in recent hardware
on-chip processing times are dominated by memory access bandwidth.
And of course one of the ways that chip-manufacturers speed things up
is by reading an entire cache line in one buss operation, which may
take dozens of CPU cycles.)
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-16  0:00             ` dennison
@ 1998-10-16  0:00               ` dewar
  0 siblings, 0 replies; 21+ messages in thread
From: dewar @ 1998-10-16  0:00 UTC (permalink / raw)


In article <707v7m$3aa$1@nnrp1.dejanews.com>,
  dennison@telepath.com wrote:
> In article <F0wCFH.In.0.-s@inmet.camb.inmet.com>,
>   stt@houdini.camb.inmet.com (Tucker Taft) wrote:
> > dennison@telepath.com wrote:
> >
> > : ...
> > : Even though this code has to be portable, I probably would have
considered
> > : cheating and using Duration if I could have found any documentation from
my
> > : compiler vendor on how it is implemented. Unfortunately, there seem to be
> > : *no* documentation requirements on Duration (unlike all *other*
predefined
> > : types), so my vendor didn't bother to document it. Lucky me.
> >
> > There should be an "annex M" which contains such information.
> >
>
> Yes, there is an annex M. No, it does not contain that information. It has
> entries for the predefined integer types declared in Standard (13), and the
> predefined floating-point types declared in Standard (17), but none for the
> predefined fixed-point types declared in Standard. As far as I can tell from
> the LRM's annex M, there are *no* documentation requirements for Duration.
> I'd be happy to be proven wrong (cuz then I could go bitch at my vendor).


Well most certainly Duration'Small must be documented, this is perfectly clear
from the RM. In M, we have

    2  Whether or not each recommendation given in Implementation Advice
       is followed.  See 1.1.2(37).

Certainly one hopes that this requirement is followed!

In section 9.6, we have

                            Implementation Advice

30   Whenever possible in an implementation, the value of Duration'Small
should be no greater than 100 microseconds.

So clearly this must be documented, and that is really what you are interested
in here. The GNAT RM contains this required documentation, and there you can
find:

@findex Duration'Small
@item 9.6(30-31): Duration'Small
@sp 1
@cartouche
Whenever possible in an implementation, the value of @code{Duration'Small}
should be no greater than 100 microseconds.
@end cartouche
Followed. (@code{Duration'Small} = 10**(-9)).


(This is the original texi source, from which we make HTML, postscript, and
the info file that emacs can view, as well as OS/2 and WinNT format help
files. The cartouche makes a nice box around the answer :-)

Robert Dewar
Ada Core Technologies

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: Simple Real_Time.Time_Span question
  1998-10-15  0:00         ` dennison
  1998-10-16  0:00           ` Tucker Taft
@ 1998-10-17  0:00           ` Niklas Holsti
  1 sibling, 0 replies; 21+ messages in thread
From: Niklas Holsti @ 1998-10-17  0:00 UTC (permalink / raw)


dennison@telepath.com wrote:
  [ snip ]
> I don't think there is much doubt that the specification of Ada.Real_Time is
> seriously broken in this respect. Until this can be addressed properly, I
> would implore Ada vendors who support this annex to provide a child package
> with subprograms capable of converting between Float and Time_Span. I realize
> Float as a type has its problems too, but between Float and Duration I think
> we would have the needs of Real-time programs fairly well covered.

In an earlier posting, I suggested converting Time_Span to Float by
means of division by Time_Span_Unit, yielding an Integer, then
multiplying by Time_Unit, giving floating-point seconds. While this
works, in experimenting with GNAT (3.05) I noticed that there is a
dynamic range problem: Time_Unit is 1 nanosecond and Integer is 32
bits, which means that the above conversion method will only work
for a Time_Span less than about 2.14 seconds ( = 2**31 nanoseconds)
before the division overflows. In a theoretical implementation with
16-bit Integer and a Time_Unit of 20 microseconds, the limit would be
about 0.66 seconds.

So although the conversion to floating point is defined by
Ada.Real_Time, the range may be too narrow for the direct
algorithm.

A work-around is possible: first divide the given Time_Span
by Integer'last * Time_Span_Unit. Multiply the quotient by
Integer'last * Time_Unit; convert the remainder as suggested
above; then add the results. This extends the convertible
Time_Span range by a factor of Integer'last, to around
146 years for GNAT.

While this work-around solves the range problem, it is a
little cumbersome. My suggestion for an LRM change is to
replace "Integer" in the Ada.Real_Time operations by a local
integer type (named Time_Count, say) of implementation-defined
range, sufficient for some standard Time_Span range such as
1 day or, preferably, 50 years. GNAT could choose a 64-bit 
integer for this type, giving a range of 292 years by
my calculations. This should be enough for anybody :-)

- Niklas Holsti




^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~1998-10-17  0:00 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-10-13  0:00 Simple Real_Time.Time_Span question dennison
1998-10-13  0:00 ` Tucker Taft
1998-10-13  0:00 ` David C. Hoos, Sr.
1998-10-13  0:00   ` dennison
1998-10-14  0:00     ` Niklas Holsti
1998-10-14  0:00       ` Niklas Holsti
1998-10-14  0:00     ` Robert I. Eachus
1998-10-14  0:00       ` Keith Thompson
1998-10-14  0:00       ` Jonathan Guthrie
1998-10-15  0:00         ` dennison
1998-10-16  0:00           ` Tucker Taft
1998-10-16  0:00             ` dennison
1998-10-16  0:00               ` dewar
1998-10-17  0:00           ` Niklas Holsti
1998-10-13  0:00 ` dennison
1998-10-14  0:00 ` dewar
1998-10-14  0:00   ` dennison
1998-10-14  0:00     ` Matthew Heaney
1998-10-14  0:00     ` Robert I. Eachus
1998-10-15  0:00       ` dennison
1998-10-16  0:00         ` Robert I. Eachus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox