4

次のコードでは:

@profile
def do():

    import random
    import numpy as np

    image = np.memmap('image.np', mode='w+', dtype=np.float32, shape=(10000, 10000))

    print("Before assignment")

    x = random.uniform(1000, 9000)
    y = random.uniform(1000, 9000)
    imin = int(x) - 128
    imax = int(x) + 128
    jmin = int(y) - 128
    jmax = int(y) + 128
    data = np.random.random((256,256))
    image[imin:imax, jmin:jmax] = image[imin:imax, jmin:jmax] + data

    del x, y, imin, imax, jmin, jmax, data

    print("After assignment")

do()

2 番目の print ステートメントで使用されるメモリは、最初の print ステートメントの最後に比べて増加しています。ここでは、memory_profiler の出力を示します。

Line #    Mem usage    Increment   Line Contents
================================================
     1                             @profile
     2                             def do():
     3    10.207 MB     0.000 MB   
     4    10.734 MB     0.527 MB       import random
     5    21.066 MB    10.332 MB       import numpy as np
     6                             
     7    21.105 MB     0.039 MB       image = np.memmap('image.np', mode='w+', dtype=np.float32, shape=(10000, 10000))
     8                             
     9    21.109 MB     0.004 MB       print("Before assignment")
    10                             
    11    21.109 MB     0.000 MB       x = random.uniform(1000, 9000)
    12    21.109 MB     0.000 MB       y = random.uniform(1000, 9000)
    13    21.109 MB     0.000 MB       imin = int(x) - 128
    14    21.109 MB     0.000 MB       imax = int(x) + 128
    15    21.113 MB     0.004 MB       jmin = int(y) - 128
    16    21.113 MB     0.000 MB       jmax = int(y) + 128
    17    21.625 MB     0.512 MB       data = np.random.random((256,256))
    18    23.574 MB     1.949 MB       image[imin:imax, jmin:jmax] = image[imin:imax, jmin:jmax] + data
    19                             
    20    23.574 MB     0.000 MB       del x, y, imin, imax, jmin, jmax, data
    21                             
    22    23.574 MB     0.000 MB       print("After assigment")

RAM は 21.109Mb から 23.574Mb に増加しました。そのコード ブロックをループに入れると、問題が発生します。

Line #    Mem usage    Increment   Line Contents
================================================
     1                             @profile
     2                             def do():
     3    10.207 MB     0.000 MB   
     4    10.734 MB     0.527 MB       import random
     5    21.066 MB    10.332 MB       import numpy as np
     6                             
     7    21.105 MB     0.039 MB       image = np.memmap('image.np', mode='w+', dtype=np.float32, shape=(10000, 10000))
     8                             
     9    21.109 MB     0.004 MB       print("Before assignment")
    10                             
    11   292.879 MB   271.770 MB       for i in range(1000):
    12                             
    13   292.879 MB     0.000 MB           x = random.uniform(1000, 9000)
    14   292.879 MB     0.000 MB           y = random.uniform(1000, 9000)
    15   292.879 MB     0.000 MB           imin = int(x) - 128
    16   292.879 MB     0.000 MB           imax = int(x) + 128
    17   292.879 MB     0.000 MB           jmin = int(y) - 128
    18   292.879 MB     0.000 MB           jmax = int(y) + 128
    19   292.879 MB     0.000 MB           data = np.random.random((256,256))
    20   292.879 MB     0.000 MB           image[imin:imax, jmin:jmax] = image[imin:imax, jmin:jmax] + data
    21                             
    22   292.879 MB     0.000 MB           del x, y, imin, imax, jmin, jmax, data
    23                             
    24   292.879 MB     0.000 MB       print("After assignment")

また、使用される RAM は反復ごとに増加します。この問題を回避する方法はありますか? それはNumpyのバグですか、それとも何か間違っていますか?

編集: これは MacOS X にあり、Numpy 1.6.2 以降 (開発バージョンを含む) で Python 2.7 および 3.2 に問題があります。

編集 2: Linux でも問題が発生しています。

4

2 に答える 2

1

私の推測では、numpyは最初にデータをバッファーに書き込み、後でファイルに書き込みます。おそらくパフォーマンス上の理由からです。

私はいくつかのテストを行いましたが、割り当て行の後、ファイルimage.npは変更されませんでした。オブジェクトを削除した後image、またはを実行した後にのみファイルが変更されましたimage.flush()。メモリが最も重要な場合は、ループに入れてimage.flush()、問題が解決するかどうかを確認できます。

于 2013-03-18T14:46:28.340 に答える
0

np.memmap最適化のため、デストラクタimage が呼び出されるまでデータが書き込まれない場合があります。imageこれを回避するには、コピー オン ライトとして開きます。

image = np.memmap('image.np', mode='c', dtype=np.float32, shape=(10000, 10000))

del imageまたは、ループごとに呼び出してから再度開くこともできますが、それは良い考えではありません。

于 2013-03-18T16:03:43.823 に答える