1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > linux 使cpu使用率升高_Linux程序性能优化:CPU的上下文切换

linux 使cpu使用率升高_Linux程序性能优化:CPU的上下文切换

时间:2023-09-19 16:50:03

相关推荐

linux 使cpu使用率升高_Linux程序性能优化:CPU的上下文切换

linux操作系统是将CPU轮流分配给任务,分时执行的。而每次执行任务时,CPU需要知道CPU寄存器(CPU内置的内存)和程序计数器PC(CPU正在执行指令和下一条指令的位置)值,这些值是CPU执行任务所依赖的环境,也就是CPU上下文

CPU上下文切换,就是把前一个任务的CPU上下文(CPU寄存器和程序计数器)保存起来,然后加载入新任务的上下文到CPU寄存器和程序计数器中,最后跳转到程序计数器所指的位置,运行新任务.

保存下来的上下文会在系统内核中,并在任务重新调度执行时再次加载进来,让任务看起来是连续执行的。

根据任务的不同,CPU上下文切换分为进程上下文切换、线程上下文切换、中断上下文切换。进程上下文切换

Linux把进程的运行空间分为内核空间和用户空间,并对进程按照特权等级划分,从内核空间Ring 0至用户空间Ring 3:Ring 0具有最高权限,可以直接访问所有资源;Ring 3只能访问受限资源,不能直接访问内存等硬件设备,需要通过系统调用嵌入到内核中,才能访问这些特权资源。

进程运行在用户空间为进程的用户态,陷入内核空间为进程的内核态。从用户态到内核态的转变,需要通过系统调用来完成,期间涉及CPU上下文的切换:先保存原来用户态指令位置,然后更新内核态指令新位置,最后执行内核态代码;系统调用结束后,恢复用户态数据,继续执行进程。一次系统调用发生二次CPU上下文切换

进程上下文切换 VS 系统调用:(1)进程上下文切换是一个进程切换到另一个进程;系统调用是同一个进程。(2)都需要进行上下文切换。(3)进程是由内核管理和调度的,切换只发生在内核态,所以进程上下文切换包括虚拟内存、栈、全局变量等用户资源,还包括内核堆栈、寄存器等内核资源;而系统调用只包括内核堆栈、寄存器等内核资源。

每次上下文切换需要几十纳秒到数微妙的CPU时间。切换次数较多,容易导致平均负载升高。

Linux通过TLB(Translation Lookaside Buffer)来管理虚拟内存到物理内存的映射关系。当虚拟内存更新后,TLB 也需要刷新,内存的访问也会随之变慢。特别是在多处理器系统上,缓存是被多个处理器共享的,刷新缓存不仅会影响当前处理器的进程,还会影响共享缓存的其他处理器的进程。

Linux为每个CPU都维护一个就绪队列,将活跃进程(正在运行和正在等待)按照优先级和等待CPU时间进行排序,优先级最高和等待时间最长的进程优先运行。所以触发进程调度的情况

(1)按照时间片轮转执行

(2)进程执行的资源不足时,该进程被挂起,系统调用其他进程

(3)进程通过睡眠函数sleep将自己挂起

(4)挂起当前进程,由优先级更高的进程运行

(5)硬件中断时,挂起CPU上的进程,转而执行内核中断服务程序。线程上下文切换

线程是调度的基本单位,而进程是资源拥有的基本单位。(1)当进程只有一个线程时,进程等于线程(2)进程拥有多个线程时,线程共享相同的虚拟内存和全局变量等资源,这些资源在上下文切换时不需要修改(3)线程也有私有的数据(栈和寄存器),上下文切换时需要保存。

不同进程中的两个线程切换,与进程的上下文切换是一样的。同一进程中两个线程,共享资源不动,切换线程中私有数据。所以同进程中线程切换,比多进程切换消耗更少资源,多线程替代多进程更有优势。中断上下文切换

中断事件会打断进程的正常调度和执行,转而调用中断处理程序,打断期间,保存当前进程状态,中断结束后,恢复原来的状态执行。

中断上下文,其实只包括内核态中断服务程序执行所必需的状态(CPU寄存器、内核堆栈、硬件中断参数等),不需要保存和恢复被打断进程的虚拟内存、全局变量等用户态资源。

中断处理比进程拥有更高的优先级,所以中断上下文切换与进程上下文切换不会同时发生。

中断次数过多,也会消耗大量CPU,降低系统整体性能。例程

vmstat用于分析系统的内存使用情况、CPU上下文切换和中断次数。

$ vmstat

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

r b swpd free buff cache si so bi bo in cs us sy id wa st

1 00 285444 290716 2682728 0 02 146 77 80 1 0 99 1 0

// cs (context switch) 每秒上下文切换次数

// in (interrupt) 每秒中断次数

// r (Running or Runable) 正在运行和等待CPU的进程数

// b (Blocked) 处于不可中断睡眠状态的进程数

pidstat查看每个进程的详细情况,-w选项,查看每个进程上下文切换情况,-wt选项,查看每个线程的上下文切换情况。

$ pidstat -w

21时57分43秒 UID PID cswch/s nvcswch/s Command

21时57分43秒0 10.050.15 systemd

21时57分43秒0 20.000.00 kthreadd

...

// cswch 每秒自愿上下文切换的次数(voluntary context switches):进程无法获取所需资源(I/O、内存不足等),导致上下文切换

// nvcswch 每秒非自愿上下文切换的次数 (non voluntary context switches):时间片已到等原因,系统强制调度,导致上下文切换,如大量进程争抢CPU

通过sysbench模拟系统多线程调度

$ sudo apt install sysbench sysstat

$ sysbench --num-threads=10 --max-time=300 --test=threads run // first terminal

$ vmstat 1 // second terminal

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

r b swpd free buff cache si so bi bo in cs us sy id wa st

0 00 278256 291152 2688492 0 000 1080 2375 1 1 98 0 0

0 00 278256 291152 2688492 0 00 12 506 2520 3 2 95 0 0

9 00 277736 291152 2688492 0 00 20 319 9189 1 1 98 0 0

8 00 277612 291152 2688492 0 000 53149 2069616 8 92 1 0 0

8 00 277636 291152 2688492 0 000 53289 2129835 9 92 0 0 0

8 00 277612 291156 2688488 0 00 12 51352 2134779 10 90 0 0 0

9 00 277604 291156 2688492 0 000 53214 2079199 10 89 1 0 0

9 00 277604 291156 2688492 0 000 51975 2106476 7 93 0 0 0

0 00 278348 291156 2688492 0 000 3978 221384 3 12 86 0 0

0 00 278348 291156 2688492 0 000 433 1017 1 1 99 0 0

0 00 278348 291156 2688492 0 000 249 789 2 0 98 0 0

// r 列就绪队列长度远远大于CPU数量

// in cs 两列陡然上升

// us sy 两列升高,sy列高表示CPU被内核占用的多

$ pidstat -w -u 1 // -w 显示进程切换指标, -u 显示CPU使用指标

22时36分03秒 UID PID %usr %system %guest %CPU CPU Command

22时36分04秒0 921 0.00 2.00 0.00 2.001 Xorg

22时36分04秒 10008703 1.00 1.00 0.00 2.001 pidstat

22时36分04秒 10008704 18.00 174.00 0.00 192.000 sysbench

22时36分03秒 UID PID cswch/s nvcswch/s Command

22时36分04秒0 921 250.002.00 Xorg

22时36分04秒 1000145984.000.00 compiz

22时36分04秒 100087031.00 314.00 pidstat

22时36分04秒 100015616 360.004.00 gnome-terminal-

22时36分04秒027490 315.000.00 kworker/u4:0

// CPU使用率 是sysbench进程拉高

// 上下文切换 由pidstat、kworker等共同拉高,并不到vmstat中上万的次数,因为更多的是sysbench线程的上下文切换

$ pidstat -wt 1 // -wt 显示线程切换指标

22时44分18秒 10008751 -4.000.00 sysbench

22时44分18秒 1000 -87514.000.00 |__sysbench

22时44分19秒 1000 -8761 14719.00 173756.00 |__sysbench

22时44分20秒 1000 -8752 15012.00 142064.00 |__sysbench

$ watch -d cat /proc/interrupts // 中断次数过高,查看该文件分析具体的中断类型

CPU0 CPU1

RES: 2418433 2089523 Rescheduling interrupts

// RES 重调度中断,唤醒空闲状态的CPU来调度新任务运行。中断值过高,说明过多任务的调度问题。

最合适的上下文切换次数:每秒上下文切换次数取决于系统本身的CPU性能,通过数百到一万以内是正常;超过一万或次数出现数量级增长,则有性能问题。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。