У меня есть несколько объектов, которые я пытаюсь выбрать, и все они имеют одинаковое (большое) представление памяти Cython в качестве атрибута. Поскольку просмотры памяти передаются по ссылке, они все используют одну и ту же память, а реализация эффективна для использования памяти.
Теперь мне нужно выбрать эти объекты и перезагрузить их, сохраняя при этом общие данные общими (если общие данные не становятсяподелился, после чего размер файла увеличивается, и невозможно прочитать в память). Обычно я думаю, что pickle распознает общие данные и просто обрабатывает их один раз, но из-за того, что представления памяти не могут быть обработаны напрямую, их необходимо преобразовать в массив numpy в методе redu для каждого объекта и метода pickle. больше не признает, что данные являются общими.
Есть ли какой-нибудь способ, которым я могу поддерживать общие данные с помощью процесса выбора / рассортировки?
Далее следует MWE:
import numpy as np
import pickle
cdef class SharedMemory:
cdef public double[:, :] data
def __init__(self, data):
self.data = data
def duplicate(self):
return SharedMemory(self.data)
def __reduce__(self):
return self.__class__, (np.asarray(self.data),)
def main():
x = SharedMemory(np.random.randn(100, 100))
duplicates = [x.duplicate() for _ in range(5)]
cdef double* pointerx = &x.data[0, 0]
cdef double* pointerd
cdef double[:, :] ddata
for d in duplicates:
ddata = d.data
pointerd = &ddata[0, 0]
if pointerd != pointerx:
print('Memory is not shared')
else:
print('Memory is shared')
print('pickling')
with open('./temp.pickle', 'wb') as pfile:
pickle.dump(x, pfile, protocol=pickle.HIGHEST_PROTOCOL)
for d in duplicates:
pickle.dump(d, pfile, protocol=pickle.HIGHEST_PROTOCOL)
with open('./temp.pickle', 'rb') as pfile:
nx = pickle.load(pfile)
nd = []
for d in duplicates:
nd.append(pickle.load(pfile))
ddata = nx.data
cdef double* pointernx = &ddata[0, 0]
for d in nd:
ddata = d.data
pointerd = &ddata[0, 0]
if pointerd != pointernx:
print('Memory is not shared')
else:
print('Memory is shared')
Поместите вышеуказанное в тест файла.pyx - цитонизировать с помощью «cythonize -a -i test.pyx». Затем "export PYTHONPATH =" $ PYTHONPATH ":."и запустите
from test import main
main()
из Python.