我开发了一个python程序,可以进行繁重的数值计算。我在具有32个Xeon CPU,64GB RAM和64位Ubuntu 14.04的Linux机器上运行它。我并行启动具有不同模型参数的多个python实例以使用多个进程,而不必担心全局解释器锁(GIL)。当我使用htop
监视cpu利用率时,我发现使用了所有核心,但大部分时间都是由内核使用的。通常,内核时间是用户时间的两倍以上。我担心系统级别会有很多开销,但我无法找到原因。
如何降低高内核CPU使用率?
我做了一些观察:
sys.setcheckinterval(10000)
(对于python2)和sys.setswitchinterval(10)
(对于python3)来增加python时间片,但这没有帮助schedtool -B PID
来影响任务计划程序,但这并没有帮助 修改
以下是htop
的屏幕截图:
我还运行了perf record -a -g
,这是perf report -g graph
的报告:
Samples: 1M of event 'cycles', Event count (approx.): 1114297095227
- 95.25% python3 [kernel.kallsyms] [k] _raw_spin_lock_irqsave ◆
- _raw_spin_lock_irqsave ▒
- 95.01% extract_buf ▒
extract_entropy_user ▒
urandom_read ▒
vfs_read ▒
sys_read ▒
system_call_fastpath ▒
__GI___libc_read ▒
- 2.06% python3 [kernel.kallsyms] [k] sha_transform ▒
- sha_transform ▒
- 2.06% extract_buf ▒
extract_entropy_user ▒
urandom_read ▒
vfs_read ▒
sys_read ▒
system_call_fastpath ▒
__GI___libc_read ▒
- 0.74% python3 [kernel.kallsyms] [k] _mix_pool_bytes ▒
- _mix_pool_bytes ▒
- 0.74% __mix_pool_bytes ▒
extract_buf ▒
extract_entropy_user ▒
urandom_read ▒
vfs_read ▒
sys_read ▒
system_call_fastpath ▒
__GI___libc_read ▒
0.44% python3 [kernel.kallsyms] [k] extract_buf ▒
0.15% python3 python3.4 [.] 0x000000000004b055 ▒
0.10% python3 [kernel.kallsyms] [k] memset ▒
0.09% python3 [kernel.kallsyms] [k] copy_user_generic_string ▒
0.07% python3 multiarray.cpython-34m-x86_64-linux-gnu.so [.] 0x00000000000b4134 ▒
0.06% python3 [kernel.kallsyms] [k] _raw_spin_unlock_irqresto▒
0.06% python3 python3.4 [.] PyEval_EvalFrameEx
似乎大部分时间花在调用_raw_spin_lock_irqsave
上。我不知道这意味着什么。
答案 0 :(得分:8)
如果内核中存在问题,则应使用OProfile或perf等分析器缩小问题范围。
即。运行perf record -a -g
,然后使用perf data
读取保存到perf report
的分析数据。另见:linux perf: how to interpret and find hotspots。
在您的情况下,高CPU使用率是由/dev/urandom
的竞争引起的 - 它只允许一个线程从中读取,但是多个Python进程正在这样做。
Python模块random
仅用于初始化。即:
$ strace python -c 'import random;
while True:
random.random()'
open("/dev/urandom", O_RDONLY) = 4
read(4, "\16\36\366\36}"..., 2500) = 2500
close(4) <--- /dev/urandom is closed
您也可以使用/dev/urandom
或os.urandom
类明确要求SystemRandom
。因此,请检查处理随机数的代码。