3

There is a performance issue when using a system call after pre-allocating big amount of memory (e.g. numpy array). The issue grows with the amount of memory.

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)

The per-iteration time increases dramatically :

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

This should not be related to virtual memory. Is it a known issue?

4

2 に答える 2

5

You seem to have narrowed the problem down to os.system() taking longer after you've allocated a large NumPy array.

Under the covers, system() uses fork(). Even though fork() is supposed to be very cheap (due to its use of copy-on-write), it turns out that things are not quite as simple.

In particular, there are known issues with Linux's fork() taking longer for larger processes. See, for example:

Both documents are fairly old, so I am not sure what the state of the art is. However, the evidence suggests that you've encountered an issue of this sort.

If you can't get rid of those system() calls, I would suggest two avenues of research:

  • Look into enabling huge pages.
  • Consider the possibility of spawning an auxiliary process on startup, whose job would be to invoke the necessary system() commands.
于 2012-05-14T16:02:27.913 に答える
4

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秒しかかかりません。したがって、割り当てにすべて(または多くの時間)かかるわけではなく、配列へのデータの割り当てにもそれほど時間はかかりませんが、配列の割り当てステータスは、システムコールにかかる時間に影響します。実行します。とても奇妙です。

于 2012-05-14T14:54:54.777 に答える