例如,如果我這樣做:在cython中如何處理np.ndarray的內存?
cdef np.ndarray[np.int64_t, ndim=1] my_array
儲存在哪裏my_array
?我會認爲,因爲我沒有告訴cython存儲在堆中,它將被存儲在堆棧中,但是在做了下面的實驗之後,它似乎將它存儲在堆上,或者以某種方式高效地進行內存管理。如何管理內存相對於my_array
?也許我錯過了一些明顯的東西,但我找不到任何文檔。
import numpy as np
cimport cython
cimport numpy as np
from libc.stdlib cimport malloc, free
def big_sum():
# freezes up:
# "a" is created on the stack
# space on the stack is limited, so it runs out
cdef int a[10000000]
for i in range(10000000):
a[i] = i
cdef int my_sum
my_sum = 0
for i in range(10000000):
my_sum += a[i]
return my_sum
def big_sum_malloc():
# runs fine:
# "a" is stored on the heap, no problem
cdef int *a
a = <int *>malloc(10000000*cython.sizeof(int))
for i in range(10000000):
a[i] = i
cdef int my_sum
my_sum = 0
for i in range(10000000):
my_sum += a[i]
with nogil:
free(a)
return my_sum
def big_numpy_array_sum():
# runs fine:
# I don't know what is going on here
# but given that the following code runs fine,
# it seems that entire array is NOT stored on the stack
cdef np.ndarray[np.int64_t, ndim=1] my_array
my_array = np.zeros(10000000, dtype=np.int64)
for i in range(10000000):
my_array[i] = i
cdef int my_sum
my_sum = 0
for i in range(10000000):
my_sum += my_array[i]
return my_sum
你爲什麼不看看生成的C文件?無論如何,我相信cython只是調用numpy函數進行分配,它調用堆中分配的PyMalloc。 numpy不*管理它的內存。它只是依靠python分配/釋放。 – Bakuriu
@Bakuriu,感謝您的評論,這是有道理的,並且有很大的幫助,但是您是否知道更詳細地解釋這些步驟的來源?我試着查看生成的C文件,但它超過6000行代碼,並且我無法理解它。 – Akavall
這幾乎肯定是堆 - 考慮到在聲明時數組的大小是未知的,numpy通常在大型數組上工作,堆棧是有限的。雖然堆棧優化在技術上是可行的,但'ndarray'可以是視圖,因此數據引用可以逃避當前的範圍。因此,在堆中實現它更簡單。如果可能,請使用MemoryView,或者閱讀http://docs.cython.org/src/tutorial/numpy.html –