我目前正在处理操作系统操作管理费用。
实际上,我正在研究进行系统调用的成本,并开发了一个简单的C++程序来观察它。
#include <iostream>
#include <unistd.h>
#include <sys/time.h>
uint64_t
rdtscp(void) {
uint32_t eax, edx;
__asm__ __volatile__("rdtscp" //! rdtscp instruction
: "+a" (eax), "=d" (edx) //! output
: //! input
: "%ecx"); //! registers
return (((uint64_t)edx << 32) | eax);
}
int main(void) {
uint64_t before;
uint64_t after;
struct timeval t;
for (unsigned int i = 0; i < 10; ++i) {
before = rdtscp();
gettimeofday(&t, NULL);
after = rdtscp();
std::cout << after - before << std::endl;
std::cout << t.tv_usec << std::endl;
}
return 0;
}这个程序很简单。
结果是非常出乎意料的:
8984
64008
376
64049
164
64053
160
64056
160
64060
160
64063
164
64067
160
64070
160
64073
160
64077输出中的奇数行是执行系统调用所需的周期数。甚至行都是t.tv_usec中包含的值(它由gettimeofday设置,是我正在学习的系统调用)。
我真的不明白这是怎么可能的:周期的数量急剧减少,从近10,000次减少到大约150次!但是timeval结构仍然在每次调用中更新!
我在不同的操作系统(debian和macos)上尝试过,结果是相似的。
即使使用了缓存,我也不认为这是可能的。进行系统调用会导致上下文切换,从用户模式切换到内核模式,我们仍然需要读取时钟才能更新时间。
有人有主意吗?
发布于 2016-04-17 15:08:17
答案呢?尝试另一个系统呼叫。在linux上有vsyscalls,它们加速了某些syscalls的工作:What are vdso and vsyscall?
简短的版本:没有执行syscall,而是内核映射了一个内存区域,进程可以在其中访问时间信息。成本?不多(没有上下文切换)。
https://stackoverflow.com/questions/36672648
复制相似问题