Linux system call speedup

Nov 16, 2019 15:35

Trying to measure the overhead cost of Linux system calls, I got the following strange result:

>./syscall.x
getting time time, ns: 30
syscall time, ns: 740 180 170 170 160 160 160 160 160 160 170 160 160 160 160 160 170 160 160 160 170 160 160 160 170 160 160 160 170 160 160 160 160 160 160 160 160 160 160 160 160 170 160 160 160 170 160 160 160 170 160 160 160 160 160 160 170 160 160 160 170 160 160 160

The source code of syscall.x is below. First, the program measures the time cost of obtaining time with get_time_number. If clock_gettime reads time from a special memory page (which I am not sure about), this will also bring that page into caches. Before measuring, check with strace -c ./syscall.x that the program indeed does not make any time-related system calls. Time obtained with a system call would be too imprecise. So, “getting time time” is the time per one call to get_time_number.

Then the program measures the time cost of the system call close with a non-existent file descriptor. I guess that checking a file descriptor should not take much time, so most time is spent in switching kernel and user contexts. Every number on the line “syscall time” is the time per one system call. The strange thing is that the first system call takes 4 times more than subsequent system calls. Is it a processor optimization or a measurement error?

#include
#include
#include
#include

#define CALL_TIME_N (1<<4)

unsigned long get_time_number(void) {
struct timespec timespec0;
if (clock_gettime(CLOCK_MONOTONIC, ×pec0) != 0) exit(17);
return 1000000000 * (unsigned long)timespec0.tv_sec
+ (unsigned long)timespec0.tv_nsec;
}

int main() {
int i;
{
unsigned long t0 = get_time_number();
for (i = CALL_TIME_N; i-- != 0;) {
get_time_number();
get_time_number();
get_time_number();
get_time_number();
get_time_number();
get_time_number();
get_time_number();
get_time_number();
}
printf("getting time time, ns: %lu\n",
(get_time_number() - t0) / ((1<<3) * CALL_TIME_N));
}
printf("syscall time, ns:");
for (i = 1<<6; i-- != 0;) {
unsigned long t0 = get_time_number();
close(7892098);
printf(" %lu", get_time_number() - t0);
}
printf("\n");
return 0;
}

computer science, linux, english

Previous post Next post
Up