首页 > 编程知识 正文

linux cpu调优,linux cpu调度

时间:2023-05-04 07:33:25 阅读:276038 作者:1084

 

我们了解到导致平均负载,有可能是以下几种方面:

CPU密集型(造成cpu利用率升高,可以理解)I/O密集型(io和cpu互斥的,也造成cpu利用率增高-不可中断进程的)大量进程(???)

根据平均负载的解释,单位时间内的处于可运行的进程和不可中断进程的进程数

System load averages is the average number of processes that are either in a runnable or uninterruptable state. A process in uninterruptable state is waiting for some I/O access, eg waiting for disk

所以我们会比较好了解CPU密集型,需要大量计算资源,会非常消耗cpu,I/O密集型需要等待I/O,会有大量的不可中断进程,

那么大量进程的情况下是如何导致平均负载升高的?

存在大量的进程竞争cpu,也就是存在大量的可运行进程,但是我们都知道cpu一个时间段其实只能运行一个进程,其他的进程也都只是在等待,并不会大量耗尽cpu资源的情况,而是cpu按照时间片给大量进程运行,所以可以想象在不停的切换不停的进程的情况下是不是也在消耗cpu资源能力,也就是我们今天要说的cpu上下文切换

Linux是一个多用户用任务的操作系统,他支持远远大于cpu的进程数运行,而cpu每次却只能运行一个任务,所以其实这些任务其实并不是在同时运行,整个过程是cpu轮流运行任务,给用户带来的假象。而当一个任务需要运行前,cpu需要知道从那里加载,从哪里开始运行,也就是系统需要事先设置好cpu寄存器和程序计数器。

cpu寄存器: cpu内置的容量小,但是速度极快的内存。程序计数器: 用来存储cpu正在执行的指令位置,或者即将执行的下一条指令位置。

它们是CPU在运行任何任务前,必须依赖的,所以也被称为CPU上下文。

所以根据上下文的了解,所谓的上下文切换:

把前一个任务的CPU上下文保存下来找到并加载新任务的上下文切换到新的cpu寄存器和程序计数器最后跳到程序计数器所指的新位置,开始运行新任务。

保存下来的上下文会存储在内核,并在任务重新调度时再加载进去,这样任务不受影响,任务看起来来也是连续运行的。

根据任务的不同,CPU上下文切换可以分几种不同场景:

 进程上下文切换线程上下文切换中断上下文切换 进程上下文切换

Linux分为内核空间和用户空间:

 

所以根据内核空间划分,一个进程可以被称为进程的用户态和进程的内核态,

当一个系统调用发生市必然会发生CPU上下文切换的,

比如我们加载存在磁盘里的一个文件,我们触发的指令是进程的用户态,而我们需要操作磁盘就需要系统调用陷入内核态,而我们原先的用户态就需要保存起来,执行内核态的指令,加载完数据就需要恢复用户态,继续运行进程,

 

所以可以知道一次系统调用会发生两次CPU上下文切换。

这里说的系统调用和进程上下文切换又是不同的:

进程上下文切换是指从一个进程切换到另一个进程系统调用始终在一个进程中运行

所以系统调用还是被称为特权模式调用,而不是上下文切换,但是系统调用导致的cpu上下文切换还是不可避免。

 

 

那么进程的上下文切换和系统调用存在什么关系?

进程是需要系统内核来管理和调度的,进程的上下文切换只能发生在内核态,

所以进程的上下文不仅包括虚拟内存、栈、全局变量等用户空间资源,还有内核堆栈、寄存器等内核空间状态

所以进程的上下文切换和系统调用(软中断)多了一个保存用户空间和恢复用户空间。

进程上下文切换过程:

接受切换信号,挂起进程,记录当前的进程的虚拟内存、栈等资源存储将这个进程在CPU的上下文状态存储然后检索下一个进程的CPU的上下文加载到CPU的寄存器中恢复还需要刷新进程保存的虚拟内存和用户栈最后跳转到程序计数器所指向的位置,恢复进程运行

而保存上下文和恢复上下文过程不是免费的,大概每次上下文切换会花费几十纳秒到数微妙之间,当大量进程时,这个cpu上下文切换是相当可观的,会花费大量时间在保存和恢复cpu上下文和用户空间状态,cpu分配给进程的时间片是一定的,导致cpu实际运行进程时间大大减少,而当时间片用完,进程必须挂起,这也是导致平均负载升高的一个因素。

什么时候需要进行进程上下文切换?

Linux会为每个cpu都维护一个就绪队列,也就是进程状态为R状态的的进程,最理想状态是之前的进程完成,cpu得到释放,下一个进程得到cpu使用,但是实际情况是不同的。

为了保证所有进程得到公平调度,CPU时间被划分一段段时间片,这些时间片轮流分给进程,当时间片耗尽,进程会被挂起,等待下一次分配cpu时间片。进程运行的系统资源不足,比如内存不足,进程必须得倒资源满足才可以运行,这个时候会被挂起,系统会调度其他可运行的进程。当进程通过睡眠函数主动挂起,会重新调度。当有高优先级的进程运行时,为保障高优先级运行,当前进程会被挂起,由高优先级进程运行。发生硬件中断,cpu上的进程会被挂起,而由内核中的中断服务运行。线程上下文切换

线程和进程的最大区别在于,线程是调度的基本单位,而进程则是资源拥有的基本单位,说白了,内核中的任务调度,调度的对象就是线程,而进程给线程提供虚拟内存、全局变量等资源。

进程与线程的比较:

当进程只有一个线程的时候,进程就等于线程当进程由多个线程的时候,这些线程会共享相同的虚拟内存与全局变量等资源,这些在上下文切换的时候不需要修改线程也是有私有数据的,这些数据在上下文切换的时候是需要保存的

所以这里也可以看出,相对于比较多进程与多线程,

多线程间的切换会比多进程间的切换消耗更少的资源。

中断上下文切换 中断软中断可以触发内核执行 We know that we can trigger the kernel to execute by generating a software interrupt.int 指令可以产生软中断

Kernel-side: int $0x80 entry point

 

为了快速响应硬件事件,中断处理会打断进程的正常调度和执行,转而执行调用中断处理程序,响应设备事件。但是和进程的上下文不同的是,

中断上下文切换不会涉及到进程的用户态,只是需要内核态中断程序执行必需的状态,并且对于一个cpu来说,中断处理比进程拥有更高的优先级。

怎么查看系统上下文切换情况

过多的cpu上下文切换会导致花费大量的时间消耗在寄存器、内核栈及虚拟内存的保存与恢复中,缩短cpu在规定时间片内真正运行的时间,导致系统性能大幅下降。

vmstat可以用来分析系统内存使用情况,也可以用来分析cpu上下文切换和中断的次数。

  r: Running or Runnable Task 是就绪队列的长度,也就是正在运行和等待CPU的进程数b: Blocked Task 处于不可中断睡眠状态的进程数cs: Context switch 是每秒上下文切换的次数in: Interrupt 则是每秒中断的次数

vmstat可以给出总体的上下文切换情况,如果想要查看每个进程的详细情况,

需要pidstat来查看:

  cswch: 表示每秒自愿上下文切换的次数nvcswch: 表示每秒非自愿上下文切换

这两种概念意味着不同的性能问题:

自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换,如I/O,内存不足等问题,就会发生大量的自愿上下文切换。非自愿上下文切换,是指进程由于时间片已到,被系统强制调度,而发生的上下文切换,比如大量进程争抢cpu,会发生大量非自愿上下文切换。上下文切换频率多少才算合适

使用sysbench模拟多线程调度瓶颈:

 

查看vmstat:

 

cs(上下文切换)突然增大到300多万,同时观测到r增大到9,远远超过了操作系统的2核,us(user)和sy(system)这两列cpu的使用率开始突增,cpu主要被内核空间占有,in列也开始增加一倍,说明中断也是一个原因。

我们从vmstat大体可以看出cpu上下文切换和中断,并且存在多个进程竞争情况,内核空间异常繁忙,接下来我们需要分析原因,需要继续分析:

 

很明显看出来cpu使用率升高是sysbench导致的,而上下文切换则是其他进程,包括非自愿上下文切换最高的pidstat,但是我们会发现自愿上下文切换比vmstat来说的300多万来说小太多了,我们需要考虑线程问题。

 

还有我们要如何查看中断突然增大:

watch -d cat /proc/interrupts

 

Rescheduling interrupts are the Linux kernel's way to wake-up an idle CPU-core to schedule a thread on it. On SMP systems, this is often done by the scheduler in a effort to spread the load across multiple CPU-cores. 重新安排中断是Linux内核唤醒空闲CPU核心以在其上安排线程的方法.在SMP系统上,这通常由调度程序完成,以便将负载分散到多个CPU核心 Function call interrupts:: software-interrupts to 软中断

所以回到上下文切换多少合适,这个数值还是取决于cpu性能,如果想要系统比较稳定,这个值可以尽量控制在几百到一万之间,如果超过一万或者指数级增量,一般都是出现性能问题。

总结:

sysbench是一款开源的多线程性能测试工具,可以执行CPU/内存/线程/IO/数据库等方面的性能测试

自愿上下文切换变多,说明进程在等待资源,可能I/O等其他问题非自愿上下文切换变多,说明进程被强制调度,争抢cpu,cpu是瓶颈中断次数增多,说明cpu被中断处理程序占用,要通过/proc/interrupts文件来分析具体的中断类

来源:极客

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。