"高无意识环境"切换意味着什么?

Ash*_*mar 16 c c++ unix linux performance

我在C中重写了一部分代码.在使用getrusage(2) C API 记录资源使用情况进行测试时.

在更改代码之前:

user time (ms): 21503
system time (ms): 372
involuntary context switches: 20
Run Code Online (Sandbox Code Playgroud)

更改后:

user time (ms): 25589
system time (ms): 80732
involuntary context switches: 821
Run Code Online (Sandbox Code Playgroud)

我看到involuntary context switches我重写的代码已经完成了很多工作.

我的问题不是如何减少上下文切换.但..

  1. 当"非自愿上下文切换"更多时会发生什么?
  2. 它会以什么方式影响系统?

PS:磁盘上没有活动,因为没有写入任何内容.它只是几次ping服务器.

更新:

增加了系统和用户时间.

程序是多线程的.在这两种情况下都会产生相同数量的线程(3k线程).只有C中的底层api被重写.

Kla*_*äck 8

只要线程/进程进行阻塞的系统调用,就可以发生自愿上下文切换.

当线程运行时间太长(通常为10毫秒)而没有进行阻塞的系统调用并且有进程等待CPU时,会发生非自愿的上下文切换.

看起来你的程序现在比以前更加CPU密集.如果你已经使它多线程,那么可能会增加.

821个上下文切换 - 根据程序的执行时间,这可能会也可能不会很多.

如果要减少上下文切换的数量,可以减少工作线程的数量,因此线程数少于CPU内核.

更新

假设两种情况下的负载相同,看起来代码修改增加了cpu的使用.如果增加负载是一个问题,您应该分析代码以找到瓶颈.检测可以帮助隔离代码的哪个部分导致问题.


小智 5

这不是对您的问题的确切答案。无论如何,@Klas 指出

当线程运行时间过长时发生非自愿上下文切换

所以我的想法是你可以检查你的线程运行时间过长。使用 perf 并在代码中查找上下文切换最常发生的位置。并可能将旧版本程序的测量值与新版本的测量值进行比较。

Perf ( https://perf.wiki.kernel.org/index.php/Tutorial ) 有这个事件context-switches。您可以测量它并在它发生的地方收集堆栈跟踪。这是测量上下文切换的示例:

perf record -e cs -g -p `pidof my_test` sleep 5
Run Code Online (Sandbox Code Playgroud)

然后检查它们发生的位置。例如,有一个 C++ 程序带有一个完全没有系统调用的不定式循环。所有开关内容都来自我的函数 stracetrace 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*)
Run Code Online (Sandbox Code Playgroud)

相反,这是对 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
Run Code Online (Sandbox Code Playgroud)