我已经重写 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
。
我的问题不是如何减少上下文切换。但是..
P.S:磁盘上没有活动,因为没有写入任何内容。它只是几次ping服务器。
更新
增加了系统和用户时间。
程序是多线程的。在这两种情况下都会产生相同数量的线程(3k线程)。只有C中的底层api被重写。
答案 0 :(得分:8)
只要线程/进程进行阻塞的系统调用,就会发生自愿上下文切换。
当线程运行时间太长(通常为10毫秒)而没有进行阻塞的系统调用且有进程等待CPU时,会发生非自愿的上下文切换。
看起来您的程序现在比以前更加耗费CPU。如果你已经使它多线程,那么可能会增加。
821个上下文切换 - 取决于程序的执行时间,这可能会也可能不会很多。
如果要减少上下文切换的次数,可以减少工作线程的数量,这样线程就会少于CPU内核。
<强>更新强>
假设两种情况下的负载相同,看起来代码修改增加了cpu的使用。如果增加负载是一个问题,您应该分析代码以找到瓶颈。 Instrumentation可以帮助隔离代码的哪一部分导致问题。
答案 1 :(得分:4)
这不是您的问题的答案。无论如何,@ 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 ++上有一个程序,带有一个不带系统调用的不定式循环。所有开关内容都来自我的函数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