模式切换涉及的开销是多少?

时间:2009-12-07 14:19:37

标签: linux-kernel switch-statement operating-system mode

很多次我读/听到由于应用程序进行模式切换(即从用户模式进入内核模式)并且在执行系统调用后开始以用户模式执行,因此进行大量系统调用等会产生效率低下通过再次进行模式切换。

我的问题是模式切换的开销是多少? cpu缓存是否被无效或tlb条目被刷新或发生什么导致开销?

请注意,我在询问模式切换所涉及的开销,而不是上下文切换。我知道模式切换和上下文切换是两个不同的事情,我完全了解与上下文切换相关的开销,但我无法理解的是模式切换导致的开销是什么?

如果可能,请提供有关特定* nix平台的一些信息,如Linux,FreeBSD,Solaris等。

此致

拉​​利

2 个答案:

答案 0 :(得分:12)

在简单的模式切换上不应该有CPU缓存或TLB刷新。

快速测试告诉我,在我的Linux笔记本电脑上,用户空间进程需要大约0.11微秒才能完成一个简单的系统调用,除了切换到内核模式和返回之外,它还可以完成大量的工作。我正在使用getuid(),它只复制内存结构中的一个整数。 strace确认系统调用重复了MAX次。

#include <unistd.h>
#define MAX 100000000
int main() {
  int ii;
  for (ii=0; ii<MAX; ii++) getuid();
  return 0;
}

我的笔记本电脑大约需要11秒,使用time ./testover测量,11秒除以1亿就可以得到0.11微秒。

从技术上讲,这是两个模式开关,所以我想你可以声称单模式开关需要0.055微秒,但是单向开关不是很有用,所以我会考虑这个后面的数字到是更相关的。

答案 1 :(得分:2)

有很多方法可以在x86 CPU上进行模式切换(我在这里假设)。对于称为功能的用户,通常的方法是执行任务跳转或呼叫(称为任务门和呼叫门)。这两个都涉及一个Task开关(相当于一个上下文切换)。在呼叫之前添加一些处理,在呼叫之后进行标准验证,以及返回。这最小化了安全模式开关。

至于Eric的时间安排,我不是Linux专家,但在我处理的大多数操作系统中,简单的系统调用缓存数据(如果可以安全地完成)在用户空间中以避免这种开销。在我看来,getuid()将是这种数据缓存的主要候选者。因此,Eric的计时可能更多地反映了用户空间中预切换处理的开销,而不是其他任何因素。