On 11-12-07 15:15, Rene Herman wrote:

On 11-12-07 14:32, Paul Rolland wrote:

On 11-12-07 13:08, David Newall wrote:

Rene Herman wrote:

(*) some local testing shows it to be almost exactly that for both out and in on my own PC -- a little over. If anyone cares, see attached little test program. The "little over" I don't worry about. 0 us delay is also fine for me and if any code was _that_ fragile it would have broken long ago.

Some results :

Okay, these vary to wildly for you and might I suppose be a serialising artifact or some such. Give me a bit and I'll try to improve it...

This might be a bit more constant, I suppose. This serialises with cpuid. Don't see a difference locally, but perhaps you do.

On a Duron 1300 with an actual ISA bus, "out" is between 1300 and 1600 for me and "in" between 1200 and 1500 with a few flukes above that which will I suppose be caused by the bus (ISA _or_ PCI) being momentarily busy or some such...

Rene.
#include <stdlib.h>
#include <stdio.h>

#include <sys/io.h>

#define LOOPS 1000

unsigned long cycles[LOOPS];

int main(void)
{
        unsigned long overhead;
        unsigned long total;
        int i;

        if (iopl(3) < 0) {
                perror("iopl");
                return EXIT_FAILURE;
        }

        /* pull it in */
        for (i = 0; i < LOOPS; i++)
                cycles[i] = 0;

        asm volatile ("cli");
        for (i = 0; i < LOOPS; i++)
                asm (
                        "xor    %%eax, %%eax    \n\t"
                        "cpuid                  \n\t"   
                        "rdtsc                  \n\t"
                        "movl   %%eax, %%esi    \n\t"   
                        "xor    %%eax, %%eax    \n\t"
                        "cpuid                  \n\t"
                        "rdtsc                  \n\t"
                        "subl   %%esi, %%eax    \n\t"

                        : "=a" (cycles[i]) : : "ecx", "edx", "ebx", "esi");
        asm volatile ("sti");

        overhead = 0;
        for (i = 0; i < LOOPS; i++)
                overhead += cycles[i];

        asm volatile ("cli");
        for (i = 0; i < LOOPS; i++)
                asm (
                        "xor    %%eax, %%eax    \n\t"
                        "cpuid                  \n\t"   
                        "rdtsc                  \n\t"
                        "movl   %%eax, %%esi    \n\t"   
                        "outb   %%al, $0x80     \n\t"
                        "xor    %%eax, %%eax    \n\t"
                        "cpuid                  \n\t"
                        "rdtsc                  \n\t"
                        "subl   %%esi, %%eax    \n\t"

                        : "=a" (cycles[i]) : : "ecx", "edx", "ebx", "esi");
        asm volatile ("sti");

        total = 0;
        for (i = 0; i < LOOPS; i++)
                total += cycles[i];
        total -= overhead;

        printf("out: %lu\n", total / LOOPS);

        asm volatile ("cli");
        for (i = 0; i < LOOPS; i++)
                asm (
                        "xor    %%eax, %%eax    \n\t"
                        "cpuid                  \n\t"   
                        "rdtsc                  \n\t"
                        "movl   %%eax, %%esi    \n\t"   
                        "inb    $0x80, %%al     \n\t"
                        "xor    %%eax, %%eax    \n\t"
                        "cpuid                  \n\t"
                        "rdtsc                  \n\t"
                        "subl   %%esi, %%eax    \n\t"

                        : "=a" (cycles[i]) : : "ecx", "edx", "ebx", "esi");
        asm volatile ("sti");

        total = 0;
        for (i = 0; i < LOOPS; i++)
                total += cycles[i];
        total -= overhead;

        printf("in : %lu\n", total / LOOPS);

        return EXIT_SUCCESS;
}

Reply via email to