@ Свен, Хм, никогда не задумывался об этом подходе, мне понадобится какой-то эксперимент, чтобы заставить его понять и понять, но это выглядит хорошо :)

лал некоторые базовые тесты производительности и потребления памяти, и мне было интересно, есть ли способ сделать вещи еще быстрее ...

У меня есть гигантский список из 70000 элементов с пустым ndarray и путь к файлу в кортеже в указанном списке.

Моя первая версия передала нарезанную копию списка каждому из процессов в многопроцессорном модуле python, но это увеличило бы использование оперативной памяти до более чем 20 гигабайт

Во второй версии я переместил его в глобальное пространство и получил к нему доступ через индекс, такой как foo [i], в цикле в каждом из моих процессов, который, кажется, помещал его в общую область памяти / семантику CoW с процессами, таким образом, он не взрывался использование памяти (остается на уровне ~ 3 гигабайта)

Однако, в соответствии с показателями производительности / трассировкой, кажется, что большая часть времени приложения теперь тратится в режиме «получения» ...

Поэтому мне было интересно, могу ли я каким-то образом превратить этот список в своего рода блокировку без чтения / чтения, чтобы я мог покончить с частью шага получения, чтобы еще больше ускорить доступ.

Изменить 1: Вот несколько верхних строчек профилирования приложения

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   65 2450.903   37.706 2450.903   37.706 {built-in method acquire}
39320    0.481    0.000    0.481    0.000 {method 'read' of 'file' objects}
  600    0.298    0.000    0.298    0.000 {posix.waitpid}
   48    0.271    0.006    0.271    0.006 {posix.fork}

Изменить 2: Вот пример структуры списка:

# Sample code for a rough idea of how the list is constructed
sim = []
for root, dirs, files in os.walk(rootdir):
    path = os.path.join(root, filename)
    image= Image.open(path)
    np_array = np.asarray(image)
    sim.append( (np_array, path) )

# Roughly it would look something like say this below
sim = List( (np.array([[1, 2, 3], [4, 5, 6]], np.int32), "/foobar/com/what.something") )

В дальнейшем список SIM-карт будет доступен только для чтения.

Ответы на вопрос(1)

Решение Вопроса

multiprocessing Модуль предоставляет именно то, что вам нужно: общий массив с необязательной блокировкой, а именноmultiprocessing.Array класс. Проходятlock=False в конструктор, чтобы отключить блокировку.

Изменить (с учетом вашего обновления): На самом деле все гораздо сложнее, чем я ожидал. Данные всех элементов в вашем списке должны быть созданы в общей памяти. Поместите ли вы сам список (то есть указатели на фактические данные) в общую память, не имеет большого значения, потому что он должен быть небольшим по сравнению с данными всех файлов. Чтобы сохранить данные файла в общей памяти, используйте

shared_data = multiprocessing.sharedctypes.RawArray("c", data)

гдеdata это данные, которые вы читаете из файла. Чтобы использовать это как массив NumPy в одном из процессов, используйте

numpy.frombuffer(shared_data, dtype="c")

который создаст представление массива NumPy для общих данных. Аналогично, чтобы поместить путь в общую память, используйте

shared_path = multiprocessing.sharedctypes.RawArray("c", path)

где путь - обычная строка Python. В ваших процессах вы можете получить к нему доступ в виде строки Python, используяshared_path.raw, Теперь добавить(shared_data, shared_path) в ваш список. Список будет скопирован в другие процессы, но фактические данные не будут.

Я изначально хотел использоватьmultiprocessing.Array для актуального списка. Это было бы вполне возможно и гарантировало бы, что сам список (то есть указатели на данные) находится в разделяемой памяти. Теперь я думаю, что это не так важно, пока фактические данные передаются.

 Sven Marnach20 янв. 2011 г., 18:18
@Pharaun: Может быть, я не правильно понял структуру вашего списка. Не могли бы вы сделать это более четко в вашем вопросе? Я уверен, чтоArray класс может быть использован для вашего приложения.
 Pharaun20 янв. 2011 г., 18:28
@ Свен, я обновил вопрос выше с грубым примером того, как список строится под edit2, так что это должно дать представление ...
 Pharaun20 янв. 2011 г., 18:12
Моя проблема в том, что мне нужен какой-то способ хранения numy ndarray + filepath. Я понимаю, что Array хранит только 1 элемент, например, 'c', он не может хранить 'char'
 Pharaun20 янв. 2011 г., 20:26
@ Свен, Хм, никогда не задумывался об этом подходе, мне понадобится какой-то эксперимент, чтобы заставить его понять и понять, но это выглядит хорошо :)
 Sven Marnach20 янв. 2011 г., 18:45
@Pharaun: ОК, я отредактирую свой ответ, чтобы сделать его более конкретным.

Ваш ответ на вопрос