From: Pascal Obry on
Dmitry A. Kazakov a �crit :
> On Sun, 11 Mar 2007 14:57:56 +0100, Pascal Obry wrote:
>
>> Dmitry A. Kazakov a �crit :
>>
>>> BTW, Ada.Calendar should use the performance counters as well, because
>> And it does.
>
> Good to know it. Do you know how does it synchronize counter ticks with
> GetSystemTime? The method I am using is a thread that periodically adjusts
> the offset.

By checking a base time against GetSystemTimeAsFileTime to avoid using
another thread. This way you have the accuracy of the performance
counter and can adjust the current time if needed (DST, manual changes...).

> BTW performance counters:
>
> http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&

A known indeed. But this affect only some hardwares.

Pascal.

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595
From: Dmitry A. Kazakov on
On Sun, 11 Mar 2007 15:37:03 +0100, Pascal Obry wrote:

> By checking a base time against GetSystemTimeAsFileTime to avoid using
> another thread. This way you have the accuracy of the performance
> counter and can adjust the current time if needed (DST, manual changes...).

I.e. it does this only once. The potential problems with this is that:

1. The accuracy of GetSystemTimeAsFileTime is very low.

2. All system calls have non-zero latencies.

3. There is a chance that the thread will be preempted between querying the
counter and calling to a system time query, which would additionally
increase the experienced latency up to milliseconds.

4. It is unclear if the time source of the system time is derived from the
performance counter. If not, they will divergent.

A thread is used to accumulate measurements of performance counters and
system time readings to get a best possible estimation out of it.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Pascal Obry on
Dmitry,

> I.e. it does this only once. The potential problems with this is that:

No it is not does once but each time a clock is requested for adjustment
if needed.

> 1. The accuracy of GetSystemTimeAsFileTime is very low.

Yes but it is not used for final clock returned value.

> 2. All system calls have non-zero latencies.
>
> 3. There is a chance that the thread will be preempted between querying the
> counter and calling to a system time query, which would additionally
> increase the experienced latency up to milliseconds.

During initialization of the runtime the performance counter and the
system time are read until this is done during a minimal amount of time.
This gives the base reference for the performance counter and the os time.

> 4. It is unclear if the time source of the system time is derived from the
> performance counter. If not, they will divergent.

No it is no.

If this is still unclear have a look at the corresponding implementation
in the GNAT sources.

Pascal.

--

--|------------------------------------------------------
--| Pascal Obry Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--| http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595
From: Dmitry A. Kazakov on
On Sun, 11 Mar 2007 18:38:58 +0100, Pascal Obry wrote:

>> I.e. it does this only once. The potential problems with this is that:
>
> No it is not does once but each time a clock is requested for adjustment
> if needed.

You mean each time Clock is called? That would be a very expensive
implementation. A periodic task would be less demanding. But ideally it
should be something sitting close to the PCI bus.

>> 1. The accuracy of GetSystemTimeAsFileTime is very low.
>
> Yes but it is not used for final clock returned value.

How so? Ada.Calendar has Split and Time_Of. Any error in
GetSystemTimeAsFileTime will show itself there, if not compensated using
some digital filtering technique.

>> 2. All system calls have non-zero latencies.
>>
>> 3. There is a chance that the thread will be preempted between querying the
>> counter and calling to a system time query, which would additionally
>> increase the experienced latency up to milliseconds.
>
> During initialization of the runtime the performance counter and the
> system time are read until this is done during a minimal amount of time.
> This gives the base reference for the performance counter and the os time.

I am lost you here. My interpretation of what you wrote above is that the
factor and offset between the readings of performance counter and
GetSystemTimeAsFileTime is readjusted each time Clock is called.

Anyway there are so many issues when reading from any clock sources, which
could prevent you from getting good measurements at once, like bus load,
interrupts, preempting etc. Also when the source of GetSystemTimeAsFileTime
is ticks, it could have systematic digitization error (1-2ms), which cannot
be compensated quickly.

> If this is still unclear have a look at the corresponding implementation
> in the GNAT sources.

That is what I am trying to avoid... (:-))

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Randy Brukardt on
"Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
news:1lo7kf2cw2mog$.94hkrwmeyhqy.dlg(a)40tude.net...
> On Sat, 10 Mar 2007 21:03:41 -0600, Randy Brukardt wrote:
>
> > "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
> > news:r5rrsmngabou$.nc73hmyyugax.dlg(a)40tude.net...
> >> On Fri, 9 Mar 2007 19:39:30 -0600, Randy Brukardt wrote:
> >>
> >>> "Dmitry A. Kazakov" <mailbox(a)dmitry-kazakov.de> wrote in message
> >>> news:p87mtsns4of0.hhld0y03415s.dlg(a)40tude.net...
> >>> ...
> >>>> As for GetThreadTimes, its absolute precision is 1ms.
> >>>
> >>> No, it is 10ms. The interface offers more precision than is actually
> >>> provided.
> >>
> >> You can force it to 1ms using
> >>
> >> timeBeginPeriod (1);
> >
> > That's documented as applying to "Multimedia timers", whatever those
are. I
> > wouldn't want to assume it would work on thread times and the like which
> > have nothing to do with multimedia. Besides, why wouldn't the maximum
> > accuracy alway be used if it is possible? What possible value is there
in
> > using a less accurate time (given that you still have to do the math on
> > every switch no matter what the accuracy is involved)??
>
> The side effect of timeBeginPeriod(1) is in changing the granularity of
> timing calls, which in turn has an impact on the overall threads
> scheduling. For example, Sleep(1) would indeed wait for 1ms, not 10ms.
That
> would be difficult to have if threads wouldn't be rescheduled faster. So
> timeBeginPeriod achieves this by changing the time resolution of the
system
> scheduler, the accuracy of the time slices should change as well.

I can believe that's true, but there is no indication of that in the
official Microsoft documentation. It only talks about multimedia; it never
mentions "sleep", for instance, so I would not want to depend on it changing
the behavior of those functions. (We only call sleep for the full 0.01
periods we want to sleep; the fractional part if any is handled by a
busy-wait loop. Nasty, but the alternative is very slow running
applications.)

In any event, that has nothing to do with the accuracy of GetThreadTimes.
There is no reason at all to have less accuracy there, because the math is
the same either way: they have to work to discard accuracy. So I don't see
why changing something in the multimedia library would matter.

> >> This what any tasking Ada program should not forget do, when it starts
> >> under Windows. I hope that GNAT RTL does this...
> >
> > Why? Ada.Real_Time is built on top of the performance counters, so is
all of
> > your tasking programs.
>
> No, the reason is to get a finer scheduler resolution. 10ms was chosen in
> the times when PCs were sufficiently slower. Now one can and should
> reschedule at 1ms tact, or even faster.

Again, I don't see any indication in the Microsoft documentation that this
function has any effect on scheduling. And if it does, what the heck is to
doing defined in and documented as part of multimedia extensions? (OK, you
can't answer that.)

> BTW, Ada.Calendar should use the performance counters as well, because
> system time calls have catastrophic accuracy. In C++ programs I translate
> performance counters into system time using some statistical algorithm.
> Better it would be to do on the driver level. I don't know why MS still
> keeps it this way.

Janus/Ada certainly does this. It uses the performance counter, and only
checks the real clock periodically to check for massive changes. Moreover,
it only re-bases if the time has changed more then 5 minutes in either
direction from the one determined by the performance counter (else we
believe the performance counter).

Tom Moran also designed code to fix the "clock leap" problem of the
performance counter (he had a computer with that problem), and the is also
part of our Calendar package.

....
> > Humm, I find that nearly impossible to believe. I'd expect some other
cause
> > (*any* other cause) before I believed that. (Outside of device drivers,
> > anyway, which would be a lousy place to use this sort of timing.) I
guess
> > I'd have to see a detailed example of that for myself before I believed
it.
>
> There is a plausible explanation of the effect. When a middleware variable
> gets changed the middleware stores it in its memory updates some internal
> structures and returns to the caller. The physical publishing I/O activity
> happens on the context of another thread and even other process. This is
> why the thread time of the publisher was always 0, it simply took less
than
> 1ms and the caller in the test application entered sleep immediately after
> publishing the variable. Even delivery was shorter, about 250um total
> latency. GetThreadTimes is absolutely unsuitable to measure anything like
> that.

I see, that says that the test harness was causing the effect. That doesn't
surprise me at all: if you *try* to put yourself into lock step with the
system, you'll surely have trouble. Wake up, do something short, then sleep
surely would have that effect. A more realistic test would probably give
real data.

Anyway, it's something to watch out for. (It wouldn't happen in the current
version of Janus/Ada, because Janus/Ada doesn't use threads -- so the entire
program is one thread, and most programs rarely sleep. But that will
probably change over time.)

> When I faced the problem, I found that some guys in a similar study
> (something about Java) had it as well. They wrote an OS extension. (Some
> people have much time to spare (:-)) They interrupted Windows each nus,
> inspected which thread had the processor and let it continue. This way
they
> could get at true thread times. Quite complicated for Ada.Execution_Times,
> isn't it? (:-))

That's why we have 1.1.3(6). This certainly seems to qualify as
"impractical"!

Randy.