2013-03-18 76 views
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() 

在第二打印語句中使用的存儲器是在第一打印語句的末尾相比增加 - 這裏的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,我看到與Python 2.7和3.2,與Numpy 1.6.2及以上(包括開發版本)的問題。

編輯2:我也看到了Linux上的問題。

回答

1

我的猜測是numpy首先將數據寫入緩衝區,然後纔將數據寫入文件。可能出於性能原因。

我做了一些測試,在完成任務後,文件image.np沒有改變。該文件只在我刪除對象image或做了image.flush()後才改變。如果內存是最重要的,你可以嘗試在你的循環中加入image.flush()來查看它是否解決了問題。

0

出於優化原因,可能不會從np.memmap中寫入數據,直到調用image的析構函數爲止。您可以通過打開image作爲寫入時複製避免這種情況:

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

,或者你可以撥打del image,然後在每次循環再開一次 - 但聽起來不像是個好主意。