Na przykład, jeśli mogę to zrobić? Pomyślałbym, że skoro nie powiedziałem cythonowi, aby zapisał na stosie, byłby on przechowywany na stosie, ale po wykonaniu następującego eksperymentu wydaje się, że jest on przechowywany na stercie lub w jakiś sposób sprawnie zarządzany pamięcią. Jak zarządza się pamięcią w odniesieniu do my_array
? Może brakuje mi czegoś oczywistego, ale nie mogłem znaleźć żadnej dokumentacji na ten temat.W jaki sposób pamięć jest obsługiwana dla np.ndarray w cython?</p> <pre><code>cdef np.ndarray[np.int64_t, ndim=1] my_array </code></pre> <p>Gdzie jest moja <code>my_array</code> przechowywane:
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
Dlaczego nie rzucić okiem na wygenerowany plik C? W każdym razie wierzę, że cython po prostu wywołuje funkcje numpy do alokacji, które wywołują 'PyMalloc', który alokuje na stercie. numpy ma * nie * zarządza swoją pamięcią. Opiera się jedynie na przydziałach/deallocacjach Pythona. – Bakuriu
@Bururiu, dziękuję za komentarz, to ma sens i bardzo pomaga, ale czy znasz źródło, które wyjaśnia te kroki bardziej szczegółowo? Próbowałem spojrzeć na wygenerowany plik C, ale zawiera on ponad 6000 linii kodu i nie mogłem tego zrozumieć. – Akavall
To prawie na pewno sterty - należy wziąć pod uwagę, że rozmiar tablicy nie jest znany w momencie deklaracji, numpy zwykle działa na dużych tablicach, a stos jest ograniczony. Chociaż optymalizacja stosu jest technicznie możliwa, 'ndarray's może być widokami, dlatego dane odniesienia mogą uciec od obecnego zakresu. W związku z tym łatwiej jest zaimplementować go w sterty. Skorzystaj z MemoryView, jeśli to możliwe, lub przeczytaj http://docs.cython.org/src/tutorial/numpy.html –