Re: interrupt latency

Richard B. Johnson
2002-08-28T12:12:36Z

[-- Attachment #1: Type: TEXT/PLAIN, Size: 3012 bytes --]

On Tue, 27 Aug 2002 yodaiken@fsmlabs.com wrote:

> On Tue, Aug 27, 2002 at 04:44:34PM -0400, Richard B. Johnson wrote:
> > On Tue, 27 Aug 2002 yodaiken@fsmlabs.com wrote:
> >

[SNIPPED...]B
>
> You can do it in a tight loop. But you cannot do it otherwise. RS232 works
> because most UARTs have fifo buffers. Old Windows did pretty well, because
> you could grab the machine and let nothing else happen.
>
> What makes me dubious about your claim is that it is easy to test
> and see that a single ISA operation can take 18 microseconds
> on most PC hardware.
>
> try:
> cli
> loop:
> read tsc
> inb
> read tsc
> compute difference
> print worst case every 1000000 times.
>
> sti
>
> run for an hour on a busy machine.
>
>

No, no, no. There is no such port read that takes 18 microseconds, even
on old '386 machines with real ISR slots. A port read on those took
almost exactly 300 nanoseconds and, in fact, was the limiting factor
for the programmed I/O devices on the ISA bus.

Modern machines, if they have an ISA bus, keep them isolated off the
end of a bridge. I/O to the printer port and the IR/RS-232 device(s)
runs through another bus, variously called the GP (General Purpose)
bus. That's where the "Super I/O chips" that are used for floppy,
keyboard, printer, and RS-232C ports, is connected.

Attached, is a directory that contains the driver code used to
qualify a proposed product design several years ago. It was used
to measure latency and the number of interrupts that could be
handled, etc. You might find it useful.

Also, there is this hack I just wrote to show how many byte reads
you can do in user-mode from the printer port. You need to run
this as root because it executes iopl().

Script started on Wed Aug 28 08:01:44 2002
# cat usermode.c
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <asm/io.h>

extern int iopl(int);

volatile int run=0;
void timer(int unused)
{
run = 0;
}

int main()
{
unsigned long count = 0;
char foo[1];
(void)iopl(3);
fprintf(stdout, "Wait.....");
fflush(stdout);
(void)signal(SIGALRM, timer);
(void)alarm(1);
run++;
while(run)
{
foo[0] = inb(0x378); /* Actually put into memory */
count++; /* This takes as long as bumping a pointer */
}
printf("\nPort reads in a second = %lu\n", count);
return 0;
}

# ./usermode
Wait.....
Port reads in a second = 666072
# exit
exit

Script done on Wed Aug 28 08:02:07 2002

So, you can see that 660,000++ bytes/second can be read and put into
memory from a printer port. If you mess around with the driver code,
you will find that 80,000 interrupts/second and 80,000 bytes/second
read and put into memory is conservative. The modern Intel machines
are very good.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.18 on an i686 machine (797.90 BogoMips).
The US military has given us many words, FUBAR, SNAFU, now ENRON.
Yes, top management were graduates of West Point and Annapolis.

[-- Attachment #2: Type: APPLICATION/octet-stream, Size: 8054 bytes --]