/* gcc -W -Wall -O2 -o portime portime.c */ #include #include #include #include #define LOOPS 10000 inline uint64_t rdtsc(void) { uint32_t hi, lo; asm ("rdtsc": "=d" (hi), "=a" (lo)); return (uint64_t)hi << 32 | lo; } inline void serialize(void) { asm ("cpuid": : : "eax", "ebx", "ecx", "edx"); } int main(void) { uint64_t tsc0, tsc1, tsc2, tsc3, tsc4; uint64_t out, in8, in6; int i; if (iopl(3) < 0) { perror("iopl"); return EXIT_FAILURE; } asm ("cli"); tsc0 = rdtsc(); for (i = 0; i < LOOPS; i++) { serialize(); serialize(); } tsc1 = rdtsc(); for (i = 0; i < LOOPS; i++) { serialize(); asm ("outb %al, $0x80"); serialize(); } tsc2 = rdtsc(); for (i = 0; i < LOOPS; i++) { serialize(); asm ("inb $0x80, %%al": : : "al"); serialize(); } tsc3 = rdtsc(); for (i = 0; i < LOOPS; i++) { serialize(); asm ("inb $0x61, %%al": : : "al"); serialize(); } tsc4 = rdtsc(); asm ("sti"); out = ((tsc2 - tsc1) - (tsc1 - tsc0)) / LOOPS; in8 = ((tsc3 - tsc2) - (tsc1 - tsc0)) / LOOPS; in6 = ((tsc4 - tsc3) - (tsc1 - tsc0)) / LOOPS; printf("out 0x80: %llu cycles\n", out); printf("in 0x80: %llu cycles\n", in8); printf("in 0x61: %llu cycles\n", in6); return EXIT_SUCCESS; }