运行多个 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 模块的初始化期间读取它,或者当您使用 SystemRandomos.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.urandomSystemRandom 类来明确要求/dev/urandom。因此,请检查您处理随机数的代码。

【讨论】:

非常感谢您的帮助!现在我知道我在寻找什么,我意识到我确实在 my 代码库中有一个错误,我会出于某种原因在每次创建某个基础对象时初始化随机数生成器。我只能在一些旧代码中找到该部分,因为我确切地知道我在寻找什么!我会尽快接受您的答复。

以上是关于运行多个 python 程序时内核 CPU 高的主要内容,如果未能解决你的问题,请参考以下文章

markdown 修复了风扇运行高,内核任务在macOS上占用500%cpu(高CPU)的问题

有没有办法利用 asyncio 的多个 CPU 内核?

在多处理中如何将 CPU 内核分配给 python 进程?

多线程如何利用多个内核?

我的 Go 程序如何让所有 CPU 内核保持忙碌状态?

操作系统概览