[squeak-dev] Delay time question

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
47 messages Options
123
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Delay time question

Robert F. Scheer-2
I compared with Jon Hylands and discovered a big difference between my
Ubuntu and his Windows results.

Time millisecondsToRun: [10 timesRepeat: [(Delay forMilliseconds: 1000)
wait]] 10015

Time millisecondsToRun: [100 timesRepeat: [(Delay forMilliseconds: 100)
wait]]  10015

Time millisecondsToRun: [1000 timesRepeat: [(Delay forMilliseconds: 10)
wait]]  13405

Time millisecondsToRun: [10000 timesRepeat: [(Delay forMilliseconds: 1)
wait]]  45728

He did the third test and got something like 10250 instead of my 13405.

Is this behavior well-known and understood or is there something wrong
with my install?  

Thanks for any help.  It's a big problem for my robot (and therefore me)
at the moment.

- Robert


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Delay time question

Igor Stasenko
2008/2/28 Robert F. Scheer <[hidden email]>:

> I compared with Jon Hylands and discovered a big difference between my
>  Ubuntu and his Windows results.
>
>  Time millisecondsToRun: [10 timesRepeat: [(Delay forMilliseconds: 1000)
>  wait]] 10015
>
>  Time millisecondsToRun: [100 timesRepeat: [(Delay forMilliseconds: 100)
>  wait]]  10015
>
>  Time millisecondsToRun: [1000 timesRepeat: [(Delay forMilliseconds: 10)
>  wait]]  13405
>
>  Time millisecondsToRun: [10000 timesRepeat: [(Delay forMilliseconds: 1)
>  wait]]  45728
>
>  He did the third test and got something like 10250 instead of my 13405.
>
>  Is this behavior well-known and understood or is there something wrong
>  with my install?
>
>  Thanks for any help.  It's a big problem for my robot (and therefore me)
>  at the moment.
>

With low numbers (like 1 ms) there is a big deviation in accuracy.
Also, keep in mind that different OSes having different minimal
measurable clock step.


>  - Robert
>
>
>



--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Delay time question

johnmci
In reply to this post by Robert F. Scheer-2

On Feb 27, 2008, at 9:50 PM, Robert F. Scheer wrote:

> Time millisecondsToRun: [1000 timesRepeat: [(Delay forMilliseconds:  
> 10)
> wait]]  13405
>
> Time millisecondsToRun: [10000 timesRepeat: [(Delay forMilliseconds:  
> 1)
> wait]]  45728

For the curious the os-x carbon vm does

Time millisecondsToRun: [1000 timesRepeat: [(Delay forMilliseconds:  
10) wait]]  10196

Time millisecondsToRun: [10000 timesRepeat: [(Delay forMilliseconds:  
1) wait]]  100916

The place you need to look at is your platform's

int ioRelinquishProcessorForMicroseconds(int microSeconds) {
        /* This operation is platform dependent. */


Yes very platform dependent, and VM flavour dependent.

When you do the code above you really are saying gee let's sleep alot.  
Then ioRelinquishProcessorForMicroseconds
runs to judge when next best to wake up to service the end of the  
Delay.  Also on unix if  the operating system says the increment for  
process switch
is oh 10 milliseconds then why you cannot actually sleep for 1 ms.

Time to break out the debugger and your source code reader and  
carefully examine what ioRelinquishProcessorForMicroseconds()
is doing.

In the far past we would just put the VM to sleep for 10 ms or 1 ms,  
but a few years back I changed that to put the vm to sleep upto the  
next point where it needed to wake up (we know that because we know at  
what time delays will trigger in the future). Tempering that is code  
that aborts the sleep if a keyboard/file handle/someting interrupt  
comes in, so  that can be serviced right away.

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Delay time question

Robert F. Scheer-2
Thanks, this is very helpful.  

I had just checked with a little C program to see that CLOCKS_PER_SEC on
my system(s) is 1000000 so that shouldn't be the limiter.  

I have a feeling that my robot is about to go down the rabbit hole.

- Robert

On Wed, 2008-02-27 at 21:17 -0800, John M McIntosh wrote:

> On Feb 27, 2008, at 9:50 PM, Robert F. Scheer wrote:
>
> > Time millisecondsToRun: [1000 timesRepeat: [(Delay forMilliseconds:  
> > 10)
> > wait]]  13405
> >
> > Time millisecondsToRun: [10000 timesRepeat: [(Delay forMilliseconds:  
> > 1)
> > wait]]  45728
>
> For the curious the os-x carbon vm does
>
> Time millisecondsToRun: [1000 timesRepeat: [(Delay forMilliseconds:  
> 10) wait]]  10196
>
> Time millisecondsToRun: [10000 timesRepeat: [(Delay forMilliseconds:  
> 1) wait]]  100916
>
> The place you need to look at is your platform's
>
> int ioRelinquishProcessorForMicroseconds(int microSeconds) {
> /* This operation is platform dependent. */
>
>
> Yes very platform dependent, and VM flavour dependent.
>
> When you do the code above you really are saying gee let's sleep alot.  
> Then ioRelinquishProcessorForMicroseconds
> runs to judge when next best to wake up to service the end of the  
> Delay.  Also on unix if  the operating system says the increment for  
> process switch
> is oh 10 milliseconds then why you cannot actually sleep for 1 ms.
>
> Time to break out the debugger and your source code reader and  
> carefully examine what ioRelinquishProcessorForMicroseconds()
> is doing.
>
> In the far past we would just put the VM to sleep for 10 ms or 1 ms,  
> but a few years back I changed that to put the vm to sleep upto the  
> next point where it needed to wake up (we know that because we know at  
> what time delays will trigger in the future). Tempering that is code  
> that aborts the sleep if a keyboard/file handle/someting interrupt  
> comes in, so  that can be serviced right away.
>
> --
> =
> =
> =
> ========================================================================
> John M. McIntosh <[hidden email]>
> Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
> =
> =
> =
> ========================================================================
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Delay time question

Andreas.Raab
In reply to this post by Robert F. Scheer-2
Robert F. Scheer wrote:
> Is this behavior well-known and understood or is there something wrong
> with my install?

This is a very well known issue. Different operating systems have very
different minimal timer resolutions. Generally speaking, on Windows and
Mac OS the timer resolution is very close to 1ms whereas most Linux
kernels have *awful* timer resolutions. I have been told that you can
recompile your kernel to fix it but I'm not sure how. The classic
benchmark to verify your timer accuracy is to do something like here:

        delay := Delay forMilliseconds: 1.
        bag := Bag new.
        1000 timesRepeat:[bag add: [delay wait] timeToRun].
        bag sortedCounts

On my box it yields "a SortedCollection(941->1 51->2 8->3)" which means
that 94.1% of the delays are true 1msec delays.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Robert F. Scheer-2
Very nice method.

My results are  "a SortedCollection(937->1 26->16 15->14 11->13 10->15
1->3)"

I thought the 2.6.20 series of Linux kernels had greatly improved the
timer issues in a big push to make multimedia applications behave well
on the desktop, which they do now quite well.

- Robert

On Wed, 2008-02-27 at 21:37 -0800, Andreas Raab wrote:

> Robert F. Scheer wrote:
> > Is this behavior well-known and understood or is there something wrong
> > with my install?
>
> This is a very well known issue. Different operating systems have very
> different minimal timer resolutions. Generally speaking, on Windows and
> Mac OS the timer resolution is very close to 1ms whereas most Linux
> kernels have *awful* timer resolutions. I have been told that you can
> recompile your kernel to fix it but I'm not sure how. The classic
> benchmark to verify your timer accuracy is to do something like here:
>
> delay := Delay forMilliseconds: 1.
> bag := Bag new.
> 1000 timesRepeat:[bag add: [delay wait] timeToRun].
> bag sortedCounts
>
> On my box it yields "a SortedCollection(941->1 51->2 8->3)" which means
> that 94.1% of the delays are true 1msec delays.
>
> Cheers,
>    - Andreas
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Igor Stasenko
In reply to this post by Andreas.Raab
2008/2/28 Andreas Raab <[hidden email]>:

> Robert F. Scheer wrote:
>  > Is this behavior well-known and understood or is there something wrong
>  > with my install?
>
>  This is a very well known issue. Different operating systems have very
>  different minimal timer resolutions. Generally speaking, on Windows and
>  Mac OS the timer resolution is very close to 1ms whereas most Linux
>  kernels have *awful* timer resolutions. I have been told that you can
>  recompile your kernel to fix it but I'm not sure how. The classic
>  benchmark to verify your timer accuracy is to do something like here:
>
>         delay := Delay forMilliseconds: 1.
>         bag := Bag new.
>         1000 timesRepeat:[bag add: [delay wait] timeToRun].
>         bag sortedCounts
>
>  On my box it yields "a SortedCollection(941->1 51->2 8->3)" which means
>  that 94.1% of the delays are true 1msec delays.
>
Here the numbers for HydraVM.
 a SortedCollection(895->2 91->1 14->3)

It can't be so precise as old VM, because delay timeouts are signaled
in separate thread as event, which is then
consumed by Interpreter as soon as possible, but it takes a little
more time (switching threads e.t.c).
Things can be more precise on multicore system.

I had a hard time fighting with delays lately.. what i can say.. this
is one of the weakest and critical points in VM and language side.

>  Cheers,
>    - Andreas
>

--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Robert F. Scheer-2

On Thu, 2008-02-28 at 07:59 +0200, Igor Stasenko wrote:

> 2008/2/28 Andreas Raab <[hidden email]>:
> > Robert F. Scheer wrote:
> >  > Is this behavior well-known and understood or is there something wrong
> >  > with my install?
> >
> >  This is a very well known issue. Different operating systems have very
> >  different minimal timer resolutions. Generally speaking, on Windows and
> >  Mac OS the timer resolution is very close to 1ms whereas most Linux
> >  kernels have *awful* timer resolutions. I have been told that you can
> >  recompile your kernel to fix it but I'm not sure how. The classic
> >  benchmark to verify your timer accuracy is to do something like here:
> >
> >         delay := Delay forMilliseconds: 1.
> >         bag := Bag new.
> >         1000 timesRepeat:[bag add: [delay wait] timeToRun].
> >         bag sortedCounts
> >
> >  On my box it yields "a SortedCollection(941->1 51->2 8->3)" which means
> >  that 94.1% of the delays are true 1msec delays.
> >
> Here the numbers for HydraVM.
>  a SortedCollection(895->2 91->1 14->3)

How does this compare to standard VM on your OS?

What is your OS?

>
> It can't be so precise as old VM, because delay timeouts are signaled
> in separate thread as event, which is then
> consumed by Interpreter as soon as possible, but it takes a little
> more time (switching threads e.t.c).
> Things can be more precise on multicore system.
>
> I had a hard time fighting with delays lately.. what i can say.. this
> is one of the weakest and critical points in VM and language side.
>
> >  Cheers,
> >    - Andreas
> >
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

johnmci
In reply to this post by Andreas.Raab
os-x carbon
  a SortedCollection(830->10 149->11 13->1 6->12 1->13 1->14)

well but it depends on the unix code to do things and that's a bit  
fuzzy at time, mind Andreas example below led to many sleepless
hours...  If you peek at the mac code it did at one time do this which  
gave 99.9% accuracy.

     err = pthread_mutex_lock(&gSleepLock);
     err =  
pthread_cond_timedwait_relative_np
(&gSleepLockCondition,&gSleepLock,&tspec);
     err = pthread_mutex_unlock(&gSleepLock);

But then someone reported dropped socket accepts because the  
pthread_cond_timedwait_relative_np would fail to service the
Socket requests and I had to revert to Ian's unix code, which on os-x  
is less accurate but better than some unix machines.

 From emails from 2002 Ian said.

NetBSD ppc:
a SortedCollection(950->20 19->19 19->21 3->18 3->22 2->30 1->25 1->8
1->10 1->14)

Linux 386:
a SortedCollection(294->1 213->2 146->3 100->4 84->5 55->6 33->7 33->8
11->10 9->11 8->9 6->13 5->12 1->14 1->17 1->18)

I noted
3.2.7b4 Mac VM gives
a SortedCollection(533->2 278->3 46->23 31->24 24->22 21->1 15->4 11-
 >21 8->5 6->25 4->26 3->27 2->6 2->14 2->18 2->28 2->35 2->42 2->43 1-
 >12 1->15 1->20 1->29 1->41 1->47)



On Feb 27, 2008, at 9:37 PM, Andreas Raab wrote:

> Robert F. Scheer wrote:
>> Is this behavior well-known and understood or is there something  
>> wrong
>> with my install?
>
> This is a very well known issue. Different operating systems have  
> very different minimal timer resolutions. Generally speaking, on  
> Windows and Mac OS the timer resolution is very close to 1ms whereas  
> most Linux kernels have *awful* timer resolutions. I have been told  
> that you can recompile your kernel to fix it but I'm not sure how.  
> The classic benchmark to verify your timer accuracy is to do  
> something like here:
>
> delay := Delay forMilliseconds: 1.
> bag := Bag new.
> 1000 timesRepeat:[bag add: [delay wait] timeToRun].
> bag sortedCounts
>
> On my box it yields "a SortedCollection(941->1 51->2 8->3)" which  
> means that 94.1% of the delays are true 1msec delays.
>
> Cheers,
>  - Andreas
>

--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Igor Stasenko
In reply to this post by Robert F. Scheer-2
2008/2/28 Robert F. Scheer <[hidden email]>:

>
>  On Thu, 2008-02-28 at 07:59 +0200, Igor Stasenko wrote:
>  > 2008/2/28 Andreas Raab <[hidden email]>:
>  > > Robert F. Scheer wrote:
>  > >  > Is this behavior well-known and understood or is there something wrong
>  > >  > with my install?
>  > >
>  > >  This is a very well known issue. Different operating systems have very
>  > >  different minimal timer resolutions. Generally speaking, on Windows and
>  > >  Mac OS the timer resolution is very close to 1ms whereas most Linux
>  > >  kernels have *awful* timer resolutions. I have been told that you can
>  > >  recompile your kernel to fix it but I'm not sure how. The classic
>  > >  benchmark to verify your timer accuracy is to do something like here:
>  > >
>  > >         delay := Delay forMilliseconds: 1.
>  > >         bag := Bag new.
>  > >         1000 timesRepeat:[bag add: [delay wait] timeToRun].
>  > >         bag sortedCounts
>  > >
>  > >  On my box it yields "a SortedCollection(941->1 51->2 8->3)" which means
>  > >  that 94.1% of the delays are true 1msec delays.
>  > >
>  > Here the numbers for HydraVM.
>  >  a SortedCollection(895->2 91->1 14->3)
>
>  How does this compare to standard VM on your OS?
>
Using croquet VM:
 a SortedCollection(951->2 47->1 1->11 1->35)

Using squeak VM:
 a SortedCollection(952->2 48->1)

Surprisingly, but HydraVM seem more precise :)

>  What is your OS?

Window$

--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Igor Stasenko
In reply to this post by johnmci
2008/2/28 John M McIntosh <[hidden email]>:
> os-x carbon
>   a SortedCollection(830->10 149->11 13->1 6->12 1->13 1->14)
>
>  well but it depends on the unix code to do things and that's a bit
>  fuzzy at time, mind Andreas example below led to many sleepless
>  hours...  If you peek at the mac code it did at one time do this which
>  gave 99.9% accuracy.
>

>      err = pthread_mutex_lock(&gSleepLock);
>      err =
>  pthread_cond_timedwait_relative_np
>  (&gSleepLockCondition,&gSleepLock,&tspec);
>      err = pthread_mutex_unlock(&gSleepLock);
>
>  But then someone reported dropped socket accepts because the
>  pthread_cond_timedwait_relative_np would fail to service the
>  Socket requests and I had to revert to Ian's unix code, which on os-x
>  is less accurate but better than some unix machines.
>
I hope if you add my sleepless hours i spent making delays for hydra,
you can come out with
better results. :)


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

johnmci

On Feb 27, 2008, at 10:40 PM, Igor Stasenko wrote:
> I hope if you add my sleepless hours i spent making delays for hydra,
> you can come out with
> better results. :)
>
>
> --  
> Best regards,
> Igor Stasenko AKA sig.


Well as the last person to fiddle with checkForInterrupts (with help  
from Tim) and to make the
external semaphore signal queues work with interrupt driven code I  
admire your courage to rewrite it all.

Noting that the semaphoresUseBufferA and semaphoresUseBufferB exist  
because I was forbidden to use
an operating system semaphore become some operating systems couldn't  
support it.

Welcome to look for holes in the logic tho.

"You know my plugin signals that external semaphore and the VM never  
sees it? Really? Got a test case? Proof?"

Why is the limit 500? Is that big enough? Aren't machines faster?
Somehow I think a ioMutexLock() might lurk in the future?


--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Robert F. Scheer-2
In reply to this post by johnmci
Thanks for the most useful responses on this question of delay timing.  

It's clear that the robot program architecture must change drastically
as a result.  Currently, there are perhaps 10 concurrent processes
looping 50 times per second servicing various serial lines carrying
sensor information or actuating motors and so forth.  Although real time
processing isn't required, it is mandatory that all processes and the
main decision loop complete every 20ms, no matter what.

It seems like the best approach is to split the serial handlers outside
of Squeak, which I can do in C without too much hassle.  The question
becomes, if the interfaces with Squeak transform to sockets and all the
concurrent loops in Squeak reduce to one single loop, polling each
socket in turn, would that complete within 20ms no matter what or are
there similar problems with statistical delays involved with sockets?

I'll talk to Jon Hylands tomorrow and hope he'll save the Squeak but at
this point I'm trying to avoid the quick reaction (some might say panic)
that I just need to go back and do it all over in C.

Thanks for your very quick and understanding replies.  This is the most
helpful community I've seen online.  

- Robert

On Wed, 2008-02-27 at 22:13 -0800, John M McIntosh wrote:

> os-x carbon
>   a SortedCollection(830->10 149->11 13->1 6->12 1->13 1->14)
>
> well but it depends on the unix code to do things and that's a bit  
> fuzzy at time, mind Andreas example below led to many sleepless
> hours...  If you peek at the mac code it did at one time do this which  
> gave 99.9% accuracy.
>
>      err = pthread_mutex_lock(&gSleepLock);
>      err =  
> pthread_cond_timedwait_relative_np
> (&gSleepLockCondition,&gSleepLock,&tspec);
>      err = pthread_mutex_unlock(&gSleepLock);
>
> But then someone reported dropped socket accepts because the  
> pthread_cond_timedwait_relative_np would fail to service the
> Socket requests and I had to revert to Ian's unix code, which on os-x  
> is less accurate but better than some unix machines.
>
>  From emails from 2002 Ian said.
>
> NetBSD ppc:
> a SortedCollection(950->20 19->19 19->21 3->18 3->22 2->30 1->25 1->8
> 1->10 1->14)
>
> Linux 386:
> a SortedCollection(294->1 213->2 146->3 100->4 84->5 55->6 33->7 33->8
> 11->10 9->11 8->9 6->13 5->12 1->14 1->17 1->18)
>
> I noted
> 3.2.7b4 Mac VM gives
> a SortedCollection(533->2 278->3 46->23 31->24 24->22 21->1 15->4 11-
>  >21 8->5 6->25 4->26 3->27 2->6 2->14 2->18 2->28 2->35 2->42 2->43 1-
>  >12 1->15 1->20 1->29 1->41 1->47)
>
>
>
> On Feb 27, 2008, at 9:37 PM, Andreas Raab wrote:
>
> > Robert F. Scheer wrote:
> >> Is this behavior well-known and understood or is there something  
> >> wrong
> >> with my install?
> >
> > This is a very well known issue. Different operating systems have  
> > very different minimal timer resolutions. Generally speaking, on  
> > Windows and Mac OS the timer resolution is very close to 1ms whereas  
> > most Linux kernels have *awful* timer resolutions. I have been told  
> > that you can recompile your kernel to fix it but I'm not sure how.  
> > The classic benchmark to verify your timer accuracy is to do  
> > something like here:
> >
> > delay := Delay forMilliseconds: 1.
> > bag := Bag new.
> > 1000 timesRepeat:[bag add: [delay wait] timeToRun].
> > bag sortedCounts
> >
> > On my box it yields "a SortedCollection(941->1 51->2 8->3)" which  
> > means that 94.1% of the delays are true 1msec delays.
> >
> > Cheers,
> >  - Andreas
> >
>
> --
> =
> =
> =
> ========================================================================
> John M. McIntosh <[hidden email]>
> Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
> =
> =
> =
> ========================================================================
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Delay time question

Andreas.Raab
Robert F. Scheer wrote:
> It's clear that the robot program architecture must change drastically
> as a result.  Currently, there are perhaps 10 concurrent processes
> looping 50 times per second servicing various serial lines carrying
> sensor information or actuating motors and so forth.  Although real time
> processing isn't required, it is mandatory that all processes and the
> main decision loop complete every 20ms, no matter what.

I am not sure why your architecture has to change dramatically as a
result. If your main problem is to make sure that that a loop is done
every 20msecs and you need to adjust for statistical delay variations,
you can simply compute the actual time the wait took and do something like:

  nextDesiredTick := Time millisecondClockValue + 20.
  [true] whileTrue:[
    self doControl.
    "note: for very, very long doControl the waitTime could be negative.
     you have to decide whether it's better to skip or to run an extra
     doControl in this case."
    waitTime := nextDesiredTick - Time millisecondClockValue.
    (Delay forMilliseconds: waitTime) wait.
    "Next desired tick is twenty msecs from last one"
    nextDesiredTick := nextDesiredTick + 20.
  ].

Not only will this adjust to statistical variations in delay but it will
also take into account the amount of time spent in doControl, including
eventual time spent in other processes due to preemption. In other
words, the above is as close to 20msecs as it possibly gets.

Also, keep in mind that no amount of C coding will increase the accuracy
of your OS' default timer. But if you happen to have a high-quality
timer it would be quite trivial to link this timer to the TimerSemaphore
and use it instead of whatever the VM gives you.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

johnmci

On Feb 27, 2008, at 11:38 PM, Andreas Raab wrote:

> Also, keep in mind that no amount of C coding will increase the  
> accuracy of your OS' default timer. But if you happen to have a high-
> quality timer it would be quite trivial to link this timer to the  
> TimerSemaphore and use it instead of whatever the VM gives you.
>
> Cheers,
>  - Andreas
>

I can't speak for Windows works but the magic on unix systems happens  
in ioRelinquishProcessorForMicroseconds

getNextWakeupTick()  is the known time we must wakeup to service the  
next delay, that is the delay wants to terminate then.

    setInterruptCheckCounter(0);   <= this ensure the interpreter  
interrupt logic fires really soon after we finish this call to switch  
perhaps to the other runable process

     now = (ioMSecs() & MillisecondClockMask);
     if (getNextWakeupTick() <= now)
         if (getNextWakeupTick() == 0)   <- with morphic this never  
happens
             realTimeToWait = 16;    <--- this value might be platform  
dependent
         else {
             return 0;  <= if time now is after the time of the next  
wakeup don't sleep.
     }
     else
         realTimeToWait = getNextWakeupTick() - now;    <==== this is  
where we estimate how long to sleep.

        platformSleep(realTimeToWait*1000);  <=== accuracy dictates how delay  
behaves.



--
=
=
=
========================================================================
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
=
=
=
========================================================================



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Delay time question

Andreas.Raab
John M McIntosh wrote:
> I can't speak for Windows works but the magic on unix systems happens in
> ioRelinquishProcessorForMicroseconds

But none of it contradicts what I said earlier - if platformSleep uses
the system's default timer (which it should) then the accuracy of C code
will be no better than the accuracy of Squeak. And if it doesn't, well
then the code is broken and you should fix it. It sure as hell works on
Windows (perhaps I can shame you into fixing it? ;-)

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Robert F. Scheer-2
In reply to this post by Andreas.Raab

On Wed, 2008-02-27 at 23:38 -0800, Andreas Raab wrote:

> Robert F. Scheer wrote:
> > It's clear that the robot program architecture must change drastically
> > as a result.  Currently, there are perhaps 10 concurrent processes
> > looping 50 times per second servicing various serial lines carrying
> > sensor information or actuating motors and so forth.  Although real time
> > processing isn't required, it is mandatory that all processes and the
> > main decision loop complete every 20ms, no matter what.
>
> I am not sure why your architecture has to change dramatically as a
> result. If your main problem is to make sure that that a loop is done
> every 20msecs and you need to adjust for statistical delay variations,
> you can simply compute the actual time the wait took and do something like:
>
>   nextDesiredTick := Time millisecondClockValue + 20.
>   [true] whileTrue:[
>     self doControl.
>     "note: for very, very long doControl the waitTime could be negative.
>      you have to decide whether it's better to skip or to run an extra
>      doControl in this case."
>     waitTime := nextDesiredTick - Time millisecondClockValue.
>     (Delay forMilliseconds: waitTime) wait.
>     "Next desired tick is twenty msecs from last one"
>     nextDesiredTick := nextDesiredTick + 20.
>   ].
>
> Not only will this adjust to statistical variations in delay but it will
> also take into account the amount of time spent in doControl, including
> eventual time spent in other processes due to preemption. In other
> words, the above is as close to 20msecs as it possibly gets.
>

Yes, I see this could make a loop time average very close to exactly the
desired value over many cycles, but my main problem is in the serial i/o
loops.  

Picture 5 serial lines.  Each has a packet of a few to a few dozen bytes
arriving every 20ms although they are not synchronous.  The data arrives
on time within a few microseconds every cycle and it must be captured.  

I was trying to use delays of around 15ms to prevent the Squeak i/o
processes from continuously tying up compute cycles trying to read the
serial lines when no data was expected.  Read a packet, delay 15ms, then
go into a tighter loop trying every 1ms until the packet was read.  

Now, I know this is a bad scheme.  Even a 1ms programmed delay could
become longer than 20ms sometimes.  So let's get rid of all programmed
delays inside the serial i/o loops.  

Well, now don't we have a situation where the cpu is tied up 100% and
the latency to switch between processes is very poor?

I probably don't understand the primitive serial methods well enough.
They seem not to block while awaiting input so that requires
continuously looping to read.  Is there a blocking method?

> Also, keep in mind that no amount of C coding will increase the accuracy
> of your OS' default timer. But if you happen to have a high-quality
> timer it would be quite trivial to link this timer to the TimerSemaphore
> and use it instead of whatever the VM gives you.
>
> Cheers,
>    - Andreas
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Robert F. Scheer-2
In reply to this post by Andreas.Raab
I forgot to be very clear about this in the last post, there is one main
reason why C would have no trouble keeping these loops all serviced.

The reads would block.  While waiting for the first byte of a packet to
come in for the next cycle, no processing cycles would be consumed.  No
delays inside loops would be needed.  

- Robert


Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Delay time question

Andreas.Raab
In reply to this post by Robert F. Scheer-2
Robert F. Scheer wrote:

> Picture 5 serial lines.  Each has a packet of a few to a few dozen bytes
> arriving every 20ms although they are not synchronous.  The data arrives
> on time within a few microseconds every cycle and it must be captured.  
>
> I was trying to use delays of around 15ms to prevent the Squeak i/o
> processes from continuously tying up compute cycles trying to read the
> serial lines when no data was expected.  Read a packet, delay 15ms, then
> go into a tighter loop trying every 1ms until the packet was read.  
>
> Now, I know this is a bad scheme.  Even a 1ms programmed delay could
> become longer than 20ms sometimes.  So let's get rid of all programmed
> delays inside the serial i/o loops.  

Ah. Now we are talking. What you want is the ability for a serial port
to issue an interrupt / signal a semaphore so that your waiting process
gets woken up when something happens. The way to do this is by fixing
the (very, very naive) serial port primitives to add something that
allows you to signal a semaphore upon data availability. There are
examples for this kind of thing in other plugins (like the socket or
async file plugin).

Also, I vaguely remember that John had built a better serial port plugin
(don't remember where I saw this but I'm sure he'll chime in) which may
very well support this out of the box.

> I probably don't understand the primitive serial methods well enough.
> They seem not to block while awaiting input so that requires
> continuously looping to read.  Is there a blocking method?

There isn't. Since Squeak doesn't use native threads internally (instead
it uses so-called "green threads") a blocking read would block the
entire VM and completely defeat the purpose of a blocking read. That's
why all such primitives are designed to simply signal a semaphore so
that the process in squeak just sits there doing something like:

   dataArrived := Semaphore new.
   self registerSemaphoreForSignallingData: dataArrived.
   [true] whileTrue:[
      dataArrived wait.
      self processData.
   ].

etc.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Delay time question

Igor Stasenko
In reply to this post by Robert F. Scheer-2
2008/2/28 Robert F. Scheer <[hidden email]>:
> I forgot to be very clear about this in the last post, there is one main
>  reason why C would have no trouble keeping these loops all serviced.
>
>  The reads would block.  While waiting for the first byte of a packet to
>  come in for the next cycle, no processing cycles would be consumed.  No
>  delays inside loops would be needed.
>
Doesn't plugins for working with serial port(s) provide you a schemes
where you can use
semaphores? So , you can block a process until some data available.
>  - Robert
>
>
>



--
Best regards,
Igor Stasenko AKA sig.

123