您当前的位置: 首页 > 

恐龙弟旺仔

暂无认证

  • 0浏览

    0关注

    282博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

cpu上下文切换对性能的影响(实战)

恐龙弟旺仔 发布时间:2022-03-28 21:33:57 ,浏览量:0

前言:

在之前CPU负载的几种情况相关文章中,我们描述了几种情况导致CPU负载高。

最神奇的就是当多个活跃进程(多于CPU个数)在执行操作时,通过vmstat命令可以看到对应的cs(context switch)很高,并同时引起了CPU的高负载。

那么为什么CPU上下文切换会引起高负载均衡呢?我们一起来学习下

1.什么是CPU上下文切换?

我们知道,现代CPU基本都是基于多核、基于抢占式。

CPU会给每个任务一定的时间分片来执行任务,当A进程时间分片使用完成之后,就会切换到下一个B进程来执行,这样使得多个进程在同一个CPU上执行成为可能。

2.引起上下文切换的场景

* 当前任务时间分片使用完成之后,CPU调度下一个任务;

* 当前任务被IO阻塞,CPU调度则挂起当前任务,执行下一个任务;

* 当前任务抢占锁资源失败,CPU调度挂起当前任务,执行下一个任务;

* 用户主动挂起当前任务;

* 硬件中断;

3.上下文切换为什么耗CPU?

简单来说,CPU要想切换一个进程执行,就需要将当前正在执行的进程任务所对应的上下文资源保存下来,等待后续CPU调度(如果不保存,等下次CPU再次调度该任务时,就不知道从哪里开始执行了)。

这些上下文资源包括:用户空间数据(虚拟内存、栈、全局变量)和内核空间数据(内核堆栈、寄存器)

所以当CPU频繁的把工作都浪费在这些上下文资源的保存、加载上,那么真正投入到任务执行中的时间就少很多了。

4.CPU上下文切换数多少算正常?

实际这个还真不好说,我们可以在机器比较空闲的时候通过vmstat命令来测试以下看看。以下是笔者的docker机器空闲情况下的切换情况

root@7bc18553126f:/# vmstat -w  3
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
 r  b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
 2  0       118168        95464       128584      1540208    0    0    23    32  105   42   3   0  96   0   0
 0  0       118168        94960       128584      1540208    0    0     0     0  249  357   0   0 100   0   0
 0  0       118168        94992       128584      1540208    0    0     0     0  213  354   0   0 100   0   0

看system这一列,in(interrupt)中断就200+,cs(context switch)上下文切换就300+的水平。

这个在笔者这里算是正常的水平。

5.模拟多线程切换

我们通过sysbench命令来模拟多个线程(多于CPU核数)切换的问题。

来看下当多线程切换时的cs/in相较于正常情况下有多大差距

5.1 sysbench模拟切换

执行以下命令,启动10个线程,执行5分钟后结束

root@7bc18553126f:/# sysbench --threads=10 --max-time=300 threads run
WARNING: --max-time is deprecated, use --time instead
sysbench 1.0.11 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 10
Initializing random number generator from current time


Initializing worker threads...

Threads started!
5.2 vmstat查看具体信息
root@7bc18553126f:/# vmstat -w  3
procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
 r  b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
 8  0       118168       103756       129456      1527740    0    0    23    32  105   72   3   0  96   0   0
 7  0       118168       103756       129456      1527740    0    0     0     0 25569 1485097  19  68  13   0   0
 7  0       118168       103504       129456      1527724    0    0     0     0 25260 1472618  18  68  14   0   0
 7  0       118168       103504       129456      1527724    0    0     0     0 25318 1480719  18  68  13   0   0

直接关注system in/cs这两列,上面空闲时的CPU切换和中断也就200 300+的样子,现在一下子飙升到100W+,说明上下文切换很疯狂

5.3 pidstat查看具体切换的进程

老规矩,我们使用 pidstat -wu的方式同时查看进程系统资源使用和切换相关数据

root@7bc18553126f:/# pidstat -wu 3
Linux 5.10.76-linuxkit (7bc18553126f) 03/13/22 _aarch64_ (4 CPU)

10:35:19      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
10:35:22        0     54333    0.33    0.00    0.00    0.00    0.33     1  watch
10:35:22        0     79233   80.67  100.00    0.00    0.00  100.00     2  sysbench

10:35:19      UID       PID   cswch/s nvcswch/s  Command
10:35:22        0     54333      1.00      2.00  watch
10:35:22        0     79426      0.33      0.00  pidstat

可以看到 PID=79233的进程CPU使用率已经100%了,实际应该是已经超过100了,system使用就已经是100了。

但是没有看到sysbench相关切换数据。

由于sysbench工具创建了多个线程来执行任务,所以在使用pidstat命令时,我们需要再加上-t来展示下线程相关信息

root@7bc18553126f:/# pidstat -wut 3
Linux 5.10.76-linuxkit (7bc18553126f) 03/13/22 _aarch64_ (4 CPU)

10:34:32      UID      TGID       TID    %usr %system  %guest   %wait    %CPU   CPU  Command
10:34:35        0     79233         -   77.33  100.00    0.00    0.00  100.00     2  sysbench
10:34:35        0         -     79234    8.00   30.67    0.00   22.33   38.67     0  |__sysbench
10:34:35        0         -     79235    7.33   31.00    0.00   21.33   38.33     2  |__sysbench
10:34:35        0         -     79236    7.00   30.33    0.00   22.00   37.33     0  |__sysbench
10:34:35        0         -     79237    7.33   31.67    0.00   22.00   39.00     1  |__sysbench
10:34:35        0         -     79238    7.67   29.67    0.00   22.00   37.33     3  |__sysbench
10:34:35        0         -     79239    8.33   30.33    0.00   23.00   38.67     3  |__sysbench
10:34:35        0         -     79240    7.67   30.33    0.00   22.00   38.00     3  |__sysbench
10:34:35        0         -     79241    8.33   29.33    0.00   22.00   37.67     2  |__sysbench
10:34:35        0         -     79242    7.67   30.33    0.00   22.67   38.00     3  |__sysbench
10:34:35        0         -     79243    8.33   29.00    0.00   22.33   37.33     0  |__sysbench

10:34:32      UID      TGID       TID   cswch/s nvcswch/s  Command
10:34:35        0     54333         -      1.00      1.33  watch
10:34:35        0         -     54333      1.00      1.33  |__watch
10:34:35        0         -     79234  23777.00 107584.67  |__sysbench
10:34:35        0         -     79235  25307.67 104601.33  |__sysbench
10:34:35        0         -     79236  25521.00 103425.00  |__sysbench
10:34:35        0         -     79237  25244.67 109579.00  |__sysbench
10:34:35        0         -     79238  23200.33 107219.67  |__sysbench
10:34:35        0         -     79239  24584.33 115980.33  |__sysbench
10:34:35        0         -     79240  23894.00 107087.33  |__sysbench
10:34:35        0         -     79241  25771.33 108859.67  |__sysbench
10:34:35        0         -     79242  22596.00 114085.00  |__sysbench
10:34:35        0         -     79243  24455.00 107223.33  |__sysbench
10:34:35        0     79356         -      0.33      0.33  pidstat
10:34:35        0         -     79356      0.33      0.33  |__pidstat

通过线程这个视角就很明显了,可以看到sysbench创建出来的多个线程,cswch/s nvcswch/s都很高,被动切换更高。

总结:

通过pidstat -wut 3命令,可以查看到进程和里面的线程CPU使用、上下文切换相关数据。

主动切换(cswch/s)多,说明大家都在等资源,这时候资源本身是瓶颈;

被动切换(nvcswch/s)多,说明大家都在被强制调度,都在争抢CPU资源,此时CPU变成了瓶颈;

参考:极客时间

关注
打赏
1655041699
查看更多评论
立即登录/注册

微信扫码登录

0.0360s