【问题标题】:performance issue : big numpy array and system call性能问题:大 numpy 数组和系统调用
【发布时间】:2012-05-22 01:49:36
【问题描述】:

在预分配大量内存(例如 numpy 数组)后使用系统调用时存在性能问题。这个问题随着内存量的增加而增加。

test.py:

import os
import sys
import time
import numpy

start = time.clock()
test = int(sys.argv[1])
a = numpy.zeros((test,500,500))
for i in range(test) :
    os.system("echo true > /dev/null")
elapsed = (time.clock() - start)
print(elapsed)

每次迭代时间急剧增加:

edouard@thorin:~/now3/code$ python test.py 100
0.64
edouard@thorin:~/now3/code$ python test.py 200
2.09
edouard@thorin:~/now3/code$ python test.py 400
14.26

这应该与虚拟内存无关。 这是一个已知问题吗?

【问题讨论】:

  • 这可能部分与您可用的连续内存量有关。即使你有很多内存,分配一个大的连续块也可能比你预期的要花费更多的时间。如果您连续多次运行python test.py 1000 测试,您是否发现所需时间有很大差异?
  • @JoeKington 对我来说,分配只需要大约 35 秒中的 1 秒来运行测试。
  • 经过进一步调查,为了清楚起见,已对问题和代码进行了修改。需要的时间有一个小的变化。是的,分配时间非常快。
  • 请提供您的 Python 版本和操作系统的详细信息。
  • python Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) [GCC 4.4.3] on linux2

标签: python performance memory numpy


【解决方案1】:

如果您不使用os.system 调用会怎样?

对我来说:

python test.py 10   # 0.14
python test.py 100  # 1.18
python test.py 1000 # 11.77

在没有os.system 的情况下,它每次大约增长一个数量级。所以,我想说你的问题出在系统调用上,而不是 numpy 的性能上(这通过进行相同的测试得到证实,除了这次注释掉代码的 numpy 部分)。此时,问题变成了“为什么重复系统调用很慢(呃)?” ...不幸的是,我没有答案。

有趣的是,如果我在 bash 中执行此操作,则没有问题(它几乎立即返回)...

time for i in `seq 1 1000`; do echo true > /dev/null; done

似乎问题不只是os.system -- subprocess.Popen 也有同样的恶意......(虽然,subprocess 可能只是在后台调用os.system,我实际上并不知道...)

编辑

这越来越好。在我之前的测试中,我离开了 numpy 数组的分配......如果你也删除了 numpy 数组的分配,测试进行得相对较快。但是,数组 (1000,800,800) 的分配只需要大约 1 秒。因此,分配不会占用所有(甚至大部分时间),并且将数据分配给数组也不会花费太多时间,但是数组的分配状态确实会影响系统调用所需的时间执行。很奇怪。

【讨论】:

  • 确实,但不要改变问题;-)。这只是一个例子。我的代码要复杂得多。
  • @user1393730 抱歉,我没有仔细阅读您的问题。我将编辑我的答案以反映问题(可能)是由于系统调用而不是使用 numpy。
【解决方案2】:

在分配大型 NumPy 数组后,您似乎已将问题缩小到 os.system() 需要更长时间。

在幕后,system() 使用 fork()。尽管fork() 应该很便宜(由于它使用了copy-on-write),但事实证明事情并不那么简单。

特别是,Linux 的fork() 存在已知问题,对于较大的进程需要更长的时间。参见,例如:

这两个文件都相当旧,所以我不确定最先进的技术是什么。但是,证据表明您遇到了此类问题。

如果您无法摆脱那些system() 电话,我建议您通过两种研究途径:

  • 研究启用大页面。
  • 考虑在启动时产生一个辅助进程的可能性,其工作是调用必要的system() 命令。

【讨论】:

  • 这是目前最好的答案。也感谢您的建议,但我最好放弃这些系统调用;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
  • 2018-07-18
相关资源
最近更新 更多