use*_*978 7 operating-system process system-calls context-switch os161
我刚开始研究系统调用.我想知道在进行系统调用时导致开销的原因.
例如,如果我们考虑getpid(),当对getpid()进行系统调用时,我的猜测是如果控件当前在子进程中,则必须进行上下文切换以进入父进程以获取pid .这会导致开销吗?
此外,当调用getpid()时,将在用户空间边界上进行一些元数据传输并进入和退出内核.那么用户空间和内核之间的常量切换是否也会导致一些开销?
我在x86-64 Linux(用-O3编译)上做了一些更精确的基准测试:
ns relative(rounded) function
4.89 1 regular_function //just a value return
6.05 1 getpid //glibc caches this one (forks invalidate the cached value)
17.7 4 sysconf(_SC_PAGESIZE)
22.6 5 getauxval(AT_EUID)
25.4 5 sysconf(_SC_NPROCESSORS_ONLN)
27.1 6 getauxval(AT_UID)
54.1 11 gettimeofday
235 48 geteuid
261 53 getuid
264 54 getppid
314 64 sysconf(_SC_OPEN_MAX)
622 127 pread@0 // IO funcs benchmarked with 1 bytes quantities
638 130 read // through a 1 Gigabyte file
1690 346 write
1710 350 pwrite@0
Run Code Online (Sandbox Code Playgroud)
最便宜的"系统调用"是通过辅助矢量(~20-30ns)的那些.中间的调用(~250-310ns)应该最准确地反映平均开销,因为在内核中应该没有太多的工作要做.
为了比较,具有小尺寸请求(<64字节=>无系统调用)的malloc + free对成本约为70-80ns(参见我在静态内存分配成本与C中动态内存分配的答案).
https://softwareengineering.stackexchange.com/questions/311165/why-isnt-there-generic-batching-syscall-in-linux-bsd/350173对于如何最小化系统调用开销有一些有趣的想法.
小智 6
例如,如果我们考虑 getpid(),当对 getpid() 进行系统调用时,我的猜测是,如果控件当前在子进程中,则必须进行上下文切换以进入父进程以获取 pid .
这里不需要切换到子进程——内核应该拥有所有可用的必要数据。在大多数情况下,内核只会在调度程序中或从系统调用返回时将上下文切换到用户空间进程。
同样,当 getpid() 被调用时,将有一些元数据跨用户空间边界传输并进入和退出内核。那么用户空间和内核的不断切换是否也会造成一些开销呢?
是的,如果getpid()
经常被调用,开销肯定会增加。有一些方法可以避免这种简单的“getter”系统调用的开销,比如getpid()
和gettimeofday()
;曾经在 Linux 下使用过的一种方法是将系统调用的(已知)结果存储在一个特殊的内存页面中。(这种机制被称为vsyscall。)