【发布时间】: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的调用者。见这里:stackoverflow.com/questions/7031210/… -
是的,您阅读
/dev/urandom的频率太高了。但是 Python 应该只在random模块的初始化期间读取它,或者当您使用SystemRandom或os.urandom明确要求它时...
标签: python linux performance multiprocessing