我开发了一个庞大的数值计算python程序。 我运行在32位Xeon CPU,64GB内存和Ubuntu 14.04 64位的Linux机器上。 我并行启动多个具有不同模型参数的python实例,以使用多个进程而不必担心全局解释器锁(GIL)。 当我使用htop
监视CPU利用率时,我发现所有内核都被使用,但大部分时间是由内核使用的。 一般来说,内核时间是用户时间的两倍多。 我担心系统级别会有很多开销,但我无法find原因。
如何减less高内核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
。 不过,我不知道这意味着什么。
如果内核中存在问题,则应使用诸如OProfile或perf等分析器来缩小问题的范围。
即运行perf record -a -g
并使用perf report
将读取的分析数据保存到perf data
。 另请参阅: linux perf:如何解释和查找热点 。
在你的情况下,高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
或者os.urandom
类来显式的请求/dev/urandom
。 所以检查你的代码是处理随机数字。