用户态切换内核态的开销测试

简介: 用户态切换内核态的开销测试

前文

纸上得来终觉浅,希望通过直观的代码测试出来内核切换的开销

测试过程

通过两段程序进行对比,第一段是进行了系统调用获取uid,第二段是直接返回一个uid的值

gcc callsystem.c -o callsystem
gcc calluser.c -o calluser

测试结果

我们可以看到带有系统调用耗时需要11秒左右,用户态的耗时0.15s,开销上的差异非常明显

系统调用的代码

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

非系统调用的代码

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

strace 跟踪系统调用

其实getuid不管系统还是用户,都是返回数字就是,测试下来可以看出差异那么大

我们使用strace跟踪一下调用

strace -c ./callsystem

下面这个uid其实已经跑不出来了,基本也就是在系统调用的时候耗时

系统调用慢的缘由

系统调用其实就是应用程序和内核空间的一票接口,因为服务是在内核中提供的,所以不能直接调用调用流程如下:

实际上,系统调用的过程首先需要把用户态切换成内核态,系统调用过程是通过软中断0x80实现的,这个是比较核心的因素,因为一旦是涉及到其他中断就需要经历和其他中断一样的过程,当年这块可是考试重点:

关键的结论其实就是,宏观上来说CPU利用率是提高了,但是实际上来说中断的工作以及处理恢复工作其实都是非常耗时的,系统调用慢的缘由便是如此!

目录
相关文章
|
1月前
|
Shell Python BI
targetcli内核态操作实战
工作中一旦遇到内核态的东西感觉操作非常困难,并且各种的权限的限制导致的操作非常困难,最终往往都是重启了事。比如进程出现了僵尸D状态,活着出现内核态数据残留,例如sysfs数据残留等
57 2
|
1月前
|
资源调度 调度 UED
CPU执行系统调用时发生中断,操作系统还能切回中断前的系统调用继续执行吗?
系统调用服务例程在执行过程中,通常不会被中断。系统调用服务例程的执行是一个原子操作,即在执行期间不会被中断。这是为了确保在系统调用服务例程执行期间对内核数据结构的一致性和完整性。
|
1月前
|
存储 安全 数据中心
系统调用与用户态陷入内核态
我们都知道操作系统中运行着很多的进程,如果普通的进程可以直接操作硬件那么这个系统的安全性没办法保障,所以操作系统分出了两种状态,一种状态是运行的代码可以操作硬件;一种状态不能操作硬件,只能切换到第一种状态去操作后再切换回来,这就是内核态和用户态。
|
调度 数据安全/隐私保护
用户态和内核态 中断处理机制
用户态和内核态 中断处理机制
251 0
|
存储 缓存 Linux
为什么进程切换比线程切换代价大,效率低?【TLB:页表缓存/快表】
为什么进程切换比线程切换代价大,效率低?【TLB:页表缓存/快表】
675 0
为什么进程切换比线程切换代价大,效率低?【TLB:页表缓存/快表】
|
Linux 调度 Android开发
RK3399平台开发系列讲解(进程调度篇)14.8、CPU 上下文切换
RK3399平台开发系列讲解(进程调度篇)14.8、CPU 上下文切换
81 0
RK3399平台开发系列讲解(进程调度篇)14.8、CPU 上下文切换
|
缓存 编译器 Linux
CPU中断控制和并发处理的内核解析
CPU中断控制和并发处理的内核解析
CPU中断控制和并发处理的内核解析
|
安全 NoSQL Linux
用户代码和操作系统代码是如何在CPU上面运行的(用户态和内核态)
用户代码和操作系统代码是如何在CPU上面运行的(用户态和内核态)
618 0
用户代码和操作系统代码是如何在CPU上面运行的(用户态和内核态)
|
Linux 安全
用户态和内核态的区别
在CPU的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃。比如:清内存、设置时钟等。如果所有的程序都能使用这些指令,那么你的系统一天死机n回就不足为奇了。
2498 0
|
Linux 调度
系统调用,上下文切换及中断概念的汇总
       仔细揣摩了一段时间.        系统调用过程,用户进程进入内核态,进程栈进入内核态栈, cpu进入内核态,cpu用户态各寄存器的值保存到内核态栈,执行内核态代码. 执行完从内核态返回到用户态,包括进程栈返回到用户态栈,cpu返回到用户态,cpu各寄存器的值用之前保存在内核态栈的值还原.  内核在执行系统调用时处于进程上下文中,current指针指向当前进程,即引发系统调用的进程。
2618 0