From: lasner@watsun.cc.columbia.edu (Charles Lasner)
Subject: Re: any SKED users out there?
Reply-To: lasner@watsun.cc.columbia.edu (Charles Lasner)
Organization: Columbia University
Date: Sun, 27 Sep 1992 13:54:08 GMT

In article <1992Sep27.050516.16253@pony.Ingres.COM> jpk@Ingres.COM (Jon Krueger) writes:
>Charles Lasner writes:
>> There's a world of difference between caring about 10's of
>> microseconds versus 10's of milliseconds.
>
>You bet.  But not to recording behavior of intact
>organisms. That's what SKED was designed for.
>10 millisecond resolution was what its applications
>needed and what it gave.

I agree; the applications I did needed more, although some of them did
qualify for the word "intact" but some could argue that it was just barely so.

>
>Realtime isn't notably "do this as fast as you can".
>It's "do this and guarantee you will complete within
>time T".  Sometimes T is measured in milliseconds, 
>sometimes microseconds, nanoseconds, or hours.

Exactly.  This is what bothers me about certain other programs hawked by
certain vendors.  They aren't capable of anything but relatively slower
units, yet use the "banner" of "real-time" application to get unwanted
praise.  Moreover, someone once defined real-time as either "fixed" or
"floating".  Clearly we're talking about the fixed kind, which is always more
difficult to pull off.  My level was into the instruction/cycle counting kind.
This has been known to be done on other machines as well, such as when people
found out that overly stripped down CPU's didn't function as expected (thinking
LAB-1103 here; someone wound up building DMA peripherals for more functions
than anticipated because the CPU was the bottleneck as compared to other
models).

Moreover, there is an industry of hardware people willing to ride on this
bandwagon.  Thus we would always get our time wasted looking through brochures
for A-D convertors when we wanted fast convertors (either continuous or
at least successive-approximation types) and instead were getting glossies
about the latest and greatest dual-slope integrator type A-D convertors. (These
are fine if your application is 3 orders of magnitude slower than ours; it's
intended for applications like digital voltmeters, etc., not fairly fast
real-time; yet these companies hear about applications that monitor liquid
levels in tanks, or super-slow chemical reactions done in so-called real-time
and assume that anyone in a real-time situation is to be lumped in, thus
we are an appropriate audience for this slow stuff :-(.)

>
>> A lot of ornate programming is needed to get the
>> performance out of the machine that it's capable of.
>
>True.  But ornate can also mean impossible to validate.
>SKED had advantages to those who wanted to write a
>variety of nontrivial realtime programs and have
>confidence that they were correct.

This is also true, but irrelevant.  Sometimes the intrusion of code that is
present merely to validate what's being done guarantees that it can't.  Merely
getting an I/O error on our disk was "fatal" to the application, so the error
routines indicated aborting the run.  Fortunately there was enough time to
check for the errors, because the disk handler itself was run by DMA as well
as the DMA that wrote the data out (during the sampling, etc.).

BTW, there is another level of task interaction that comes up here: too-fast
disks that need to be "throttled back" to allow enough cycles to get the
job done.  While one constraint is the disk being fast enough on average to
keep up with the aggregate sampling rate, another constraint is that when the
disk is actually transferring, it doesn't take too many CPU cycles that the
sampling routines (on clock interrupt) are adversely affected.  All too often,
a disk transfers all of its data at once, and can be granted virtually every
buss cycle for a brief period, which should it coincide with an interrupt
handling routine that has a short critical window, means that the application
has failed to keep up with the data.  By slowing down the transfer rate, 
this can be avoided.

For one such application, there was a better solution: an inter-processor
buffer (DB8E).  This allowed one machine to carry out the real-time application
while the other machine (with the too-fast disk) acted as a disk server.  When
both machines are available, the DB8E transfers words quite quickly in the
background.  The background code is interrupted as necessary by the clock-
driven events.  Most of the time is spent in the background shoveling 12-bit
words at the disk server machine.  Periodically, the disk server is not
available as its cycles are taken away by the fast disk, which can afford to 
get certain kinds of errors and yet, through multiple buffers still keep up
if the recovery is successful after at most 2 retries.  But usually, the
disk server is available in the real-time sense.  Thus each CPU's need to
service some higher-priority task doesn't interfere with the other's.  As 
long as both machines were available to each other 60% of the time, the
data transfer was successful.

I mentioned a few articles back about the need for two clocks.  The reason
for this only tends to come up when the data rate is high:  You need to
put the clock into the mode that schedules the first of N A-D conversions
when the clock overflows, and then auto-reloads the clock counter from the
clock buffer/preset register.  The interrupt handler for the clock does a
blind read of the A-D buffer because sufficient microseconds have gone by
since the clock overflow interrupt which is what's checked for in the
interrupt routine.  Then, additional channels are scheduled, etc.  This
all works fine if that's all you want to do.

However, we also needed to use the Schmitt trigger hardware to put the
clock into the mode that dumps the clock counter into the buffer register
to count frequency of the events hooked up there.  Needless to say we were
running the clock at the 1 microsecond/tick rate at the time.  This can
be done only with two clocks, each doing one of the operations.  It was
once tried with one clock:

You have the clock overflow, and you load the buffer-preset register with
the new value of the clock counter for next time.  The problem is that
the single register is the only avenue of loading the clock counter, so
it's necessary to do it this way.  The instructions are either AC -> clock
buffer, or AC -> clock buffer -> clock counter; there is no way to leave
undisturbed the buffer register.  So, you run the clock in that mode that
reloads the clock from the buffer every time the counter overflows and
interrupts.  So far so good.  But, you also enable the Schmitt trigger
inputs, thus they also interrupt occasionally.  Perhaps even relatively
infrequently (not in our applications when data was at the expected highest
value of valid data, but the problem exists even if the data is slower).
When the Schmitt trigger interrupt occurs, what we want to do is to load the
clock buffer with what's currently in the clock right now, and then read it
into the AC.  (This is what the instruction does; the basic problem is that
there is only one path in and out of the clock counter for all functions.)
Then we quickly want to restore the constant reload factor back to the buffer
so it's correct for when the clock overflows (usually in awhile) so it will
reload correctly at that time.  (Again, this is reasonable because the 
instruction used is AC -> clock buffer only.)

But there is an insidious problem:  what if the clock is nearly ready to
overflow?  You have just dumped out the clock counter into the buffer register
and could have a clock count of something like -20 through -1.  If this is the
case, the clock will in just a few CPU instruction times be overflowing and
before you can do anything about it start reloading itself from this unintended
buffer value.  The worst case is if the clock count is -1, because it means 
that the clock is now repeatedly going -1, 0, -1, 0, -1, 0, etc. and there's
nothing you can do about it :-(.  By the time you have reloaded the buffer
with the larger number intended to be there (such as -800) some semi-unknown
amount of cycles may have gone by where the clock was out of control causing
multiple overflow/auto-reload events.  If a DMA disk is stealing cycles during
this worst-case event, the results aren't even fully predictable.  Thus, the
overall effect is a "creeping" loss of real-time :-(.  The only reliable
solution is to redesign the clock.  In our case, we did by using two clocks
to avoid the interaction.  There was enough program time available to service
the two interrupts.

BTW, there is a logistic problem in modifying the DK8EP hardware: they never
intended the clock to be anything other than device 13, whereas most cards
have spare device codes or even free-choice in a six-bit range.  We had to
hack on the logic to make it respond to device 14 :-(.

>
>SKED's "tick" was configurable, by the way.  The default
>was 10 msec, but you could set it as low as 1 msec (on
>8's) or as high as you wanted and run more stations.

We just had one faster station.

>
>-- Jon
>--
>Jon Krueger  jpk@ingres.com  

cjl





Xref: sparky alt.sys.pdp8:19 alt.folklore.computers:14783 misc.forsale.computers:35936