在处理大型numpy数组时,Python随机降低到0%的CPU使用率,导致代码“挂断”?

时间:2017-01-30 18:29:07

标签: python arrays numpy

我一直在运行一些代码,其中一部分从二进制文件加载一个大的1D numpy数组,然后使用numpy.where()方法更改数组。

以下是代码中执行的操作示例:

import numpy as np
num = 2048
threshold = 0.5

with open(file, 'rb') as f:
    arr = np.fromfile(f, dtype=np.float32, count=num**3)
    arr *= threshold

arr = np.where(arr >= 1.0, 1.0, arr)
vol_avg = np.sum(arr)/(num**3)

# both arr and vol_avg needed later

我已经多次运行(在免费的机器上,即没有其他禁止CPU或内存使用),没有问题。但最近我注意到,有时候代码会挂起很长一段时间,使运行时间长一个数量级。在这些情况下,我一直在监视%CPU和内存使用率(使用gnome系统监视器),并发现python的CPU使用率降至0%。

在上述操作之间使用基本打印进行调试,似乎是任意的,因为哪个操作导致暂停(即open(),np.fromfile(),np.where()各自分别导致挂起随机运行)。就好像我被随机扼杀一样,因为在其他运行中没有任何挂起。

我考虑过像垃圾收集或this question这样的事情,但我看不出与我的问题有任何明显的关系(例如击键没有效果)。

进一步说明:二进制文件为32GB,机器(运行Linux)有256GB内存。我通过ssh会话远程运行此代码。

编辑:这可能是偶然的,但我注意到,如果我在重新启动机器后运行代码,则没有挂断。似乎它们在几次运行之后开始发生,或者至少是系统的其他用途。

3 个答案:

答案 0 :(得分:1)

np.where正在那里创建一个副本并将其分配回arr。因此,我们可以通过避免复制步骤来优化内存,如此 -

vol_avg = (np.sum(arr) - (arr[arr >=  1.0] - 1.0).sum())/(num**3)

我们正在使用boolean-indexing选择大于1.0的元素,并从1.0获取它们的偏移量并将它们相加并从总和中减去。希望这些超出元素的数量较少,因此不会引起更明显的内存需求。我假设这个挂起问题的大型数组是基于内存的。

答案 1 :(得分:0)

CPU使用率下降与python或numpy无关,但确实是从共享磁盘读取的结果,而网络I / O是真正的罪魁祸首。对于如此大的阵列,读入内存可能是一个主要的瓶颈。

答案 2 :(得分:0)

您单击还是选择“控制台”窗口?此行为可以“挂起”该过程。控制台进入“ QuickEditMode”。按任意键可以恢复该过程。