“高非自愿上下文切换”是什么意思?

18

我已经重新编写了C语言代码的一部分。在使用getrusage(2) C API记录资源使用情况时进行测试。

更改代码之前:

user time (ms): 21503
system time (ms): 372
involuntary context switches: 20

更改后:

user time (ms): 25589
system time (ms): 80732
involuntary context switches: 821

我看到在我重写的代码中有很多“非自愿上下文切换”(involuntary context switches)。
我的问题不是关于如何减少上下文切换,而是:
1. 当“非自愿上下文切换”更多时会发生什么?
2. 它将以何种方式影响系统?
附注:磁盘上没有活动,因为没有写入任何内容。它只是多次ping服务器。
更新:
添加了系统和用户所花费的时间。
程序是多线程的。在两种情况下都生成了相同数量的线程(3k个线程)。只是C语言底层API被重新编写。
2个回答

10

当一个线程/进程调用一个阻塞式系统调用时,就会发生自愿上下文切换。

当一个线程运行时间过长(通常是10毫秒),没有进行阻塞式系统调用并且有进程在等待CPU时,就会发生非自愿上下文切换。

看起来你的程序现在比之前更加CPU密集。如果你将其变成了多线程,那么增加是很正常的。

821次上下文切换-根据程序的执行时间,这可能是很多或不多。

如果你想减少上下文切换的次数,可以减少工作线程的数量,使线程数少于CPU核心数。

更新

假设负载在两种情况下相同,看起来代码修改增加了CPU使用率。如果增加的负载是一个问题,你应该分析代码找到瓶颈。Instrumentation可以帮助隔离引起问题的代码部分。


6
这不是完全回答你的问题。不管怎样,@Klas指出当线程运行时间过长时会发生非自愿上下文切换。所以我的想法是您可以检查哪些线程运行时间过长。使用Perf并找到您的代码中发生上下文切换最频繁的地方。可能将旧版本程序的测量结果与新版本进行比较。
Perf(https://perf.wiki.kernel.org/index.php/Tutorial)有一个名为context-switches的事件。您可以测量它并收集其发生位置的堆栈跟踪。这是测量上下文切换的示例:
perf record -e cs -g -p `pidof my_test` sleep 5

然后检查它们发生的位置。例如,有一个C++程序,其中有一个无限循环而没有任何系统调用。所有switch内容都有来自我的函数my_thread_func的跟踪信息:

perf report --stdio -g --kallsym=/boot/System.map-2.6.32-431.el6.x86_64

# Samples: 7  of event 'cs'
# Event count (approx.): 7
#
# Overhead  Command      Shared Object                         Symbol
# ........  .......  .................  .............................
#
   100.00%  my_test  [kernel.kallsyms]  [k] perf_event_task_sched_out
            |
            --- perf_event_task_sched_out
                schedule
                retint_careful
                my_thread_func(void*)

相反,这是一个使用C ++编写的程序的度量标准,该程序具有大量系统调用的无限循环:

# Samples: 6  of event 'cs'
# Event count (approx.): 6
#
# Overhead          Command      Shared Object                         Symbol
# ........  ...............  .................  .............................
#
   100.00%  my_test_syscall  [kernel.kallsyms]  [k] perf_event_task_sched_out
            |
            --- perf_event_task_sched_out
                schedule
               |
               |--83.33%-- sysret_careful
               |          syscall
               |
                --16.67%-- retint_careful
                          syscall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接