运行多个 python 程序时内核 CPU 高
Posted
技术标签:
【中文标题】运行多个 python 程序时内核 CPU 高【英文标题】:High Kernel CPU when running multiple python programs 【发布时间】:2015-05-14 19:34:31 【问题描述】:我开发了一个 python 程序来进行繁重的数值计算。我在具有 32 个 Xeon CPU、64GB RAM 和 Ubuntu 14.04 64 位的 linux 机器上运行它。我并行启动具有不同模型参数的多个 python 实例以使用多个进程,而不必担心全局解释器锁 (GIL)。当我使用htop
监控 CPU 利用率时,我看到所有内核都已使用,但大部分时间都是内核使用的。通常,内核时间是用户时间的两倍以上。恐怕系统级别的开销很大,但我无法找到原因。
如何降低高内核 CPU 使用率?
以下是我的一些观察:
无论我运行 10 个作业还是 50 个作业,此效果的出现都无关。如果作业少于内核,则不是所有内核都被使用,但内核使用的内核仍然有很高的 CPU 使用率 我使用numba 实现了内部循环,但问题与此无关,因为删除 numba 部分并不能解决问题 我也认为这可能与使用类似于problem mentioned in this SO question 的 python2 有关,但从 python2 切换到 python3 并没有太大变化 我测量了操作系统执行的上下文切换的总数,大约是每秒 10000 次。我不确定这是否是一个很大的数字 我尝试通过设置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
上。不过,我不知道这意味着什么。
【问题讨论】:
您是否检查过系统上正在运行的其他内容?top
的输出会很有趣。
我没有任何异常。这甚至不是我用于日常工作的计算机。我在问题中添加了屏幕截图。
请从根目录运行perf record -a
(chdir 到/tmp
),然后运行perf report
。它会告诉你内核在做什么。
@DavidZwicker:不,它只是意味着在内核中竞争自旋锁,但我们不知道哪个自旋锁。尝试使用-g
选项调用perf record -a -g
,它将收集_raw_spin_lock_irqsave
的调用者。见这里:***.com/questions/7031210/…
是的,您阅读/dev/urandom
的频率太高了。但是 Python 应该只在 random
模块的初始化期间读取它,或者当您使用 SystemRandom
或 os.urandom
明确要求它时...
【参考方案1】:
如果问题存在于内核中,您应该使用诸如 OProfile 或 perf 之类的分析器来缩小问题范围。
即运行perf record -a -g
,然后使用perf report
读取保存到perf data
的分析数据。另见: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
您也可以通过使用os.urandom
或SystemRandom
类来明确要求/dev/urandom
。因此,请检查您处理随机数的代码。
【讨论】:
非常感谢您的帮助!现在我知道我在寻找什么,我意识到我确实在 my 代码库中有一个错误,我会出于某种原因在每次创建某个基础对象时初始化随机数生成器。我只能在一些旧代码中找到该部分,因为我确切地知道我在寻找什么!我会尽快接受您的答复。以上是关于运行多个 python 程序时内核 CPU 高的主要内容,如果未能解决你的问题,请参考以下文章