系统通话费用

时间:2016-04-17 04:22:43

标签: c++ operating-system system-calls cpu-cache

我目前正在处理操作系统操作开销。

我实际上正在研究进行系统调用的成本,并且我开发了一个简单的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;
}

这个程序非常简单。

  • rdtscp函数只是调用RTDSCP指令的包装器(处理器指令将64位循环计数加载到两个32位寄存器中)。此功能用于计时。
  • 我迭代了10次。在每次迭代中,我调用gettimeofday并确定执行它所花费的时间(作为多个CPU周期)。

结果非常意外:

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),结果很相似。

即使使用缓存,我也看不出它是如何可能的。进行系统调用应该导致上下文切换从用户切换到内核模式,我们仍然需要读取时钟以更新时间。

有人有想法吗?

1 个答案:

答案 0 :(得分:3)

答案是什么?尝试另一个系统调用。 Linux上有vsyscalls,它们可以加速某些系统调用的速度: What are vdso and vsyscall?

简短版本:不执行系统调用,而是内核映射进程可以访问时间信息的内存区域。费用?不多(没有上下文切换)。