Требуется больше времени для доступа к общей памяти, чем для загрузки из файла? - PullRequest
0 голосов
/ 02 октября 2018

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

в соответствии с этим ответом, я должен использовать Shared ctypes Objects

Типы менеджера созданы для гибкости, а не эффективности ... это обязательно означает копирование любого объекта, о котором идет речь..... Если вам нужна общая физическая память, я предлагаю использовать Shared ctypes Objects .Они на самом деле указывают на общее место в памяти, и, следовательно, они намного быстрее и требуют меньше ресурсов.

, поэтому я сделал это:

import time
import pickle
import multiprocessing
from functools import partial

def foo(_, v):
    tp = time.time()
    v = v.value
    print(hex(id(v)))
    print(f'took me {time.time()-tp} in process')

if __name__ == '__main__':
    # creates a file which is about 800 MB
    with open('foo.pkl', 'wb') as file:
        pickle.dump('aaabbbaa'*int(1e8), file, protocol=pickle.HIGHEST_PROTOCOL)

    t1 = time.time()
    with open('foo.pkl', 'rb') as file:
        contract_conversion = pickle.load(file)
    print(f'load took {time.time()-t1}')

    m = multiprocessing.Manager()
    vm = m.Value(str, contract_conversion, lock=False)  # not locked because i only read from it so its safe
    foo_p = partial(foo, v=vm)

    tpo = time.time()
    with multiprocessing.Pool() as pool:
       pool.map(foo_p, range(4))
    print(f'took me {time.time()-tpo} for pool stuff')

однако я вижу, чтопроцессы используют его копию (оперативная память в каждом процессе очень высокая), и он НАМНОГО медленнее, чем простое чтение с диска.


печать:

load took 0.8662333488464355
0x1c736ca0040
took me 2.286606550216675 in process
0x15cc0404040
took me 3.178203582763672 in process
0x1f30f049040
took me 4.179721355438232 in process
0x21d2c8cc040
took me 4.913192510604858 in process
took me 5.251579999923706 for pool stuff

такжеid - это не то же самое, хотя я не уверен, является ли id просто идентификатором Python или местом в памяти.

1 Ответ

0 голосов
/ 02 октября 2018

Вы не используете общую память.Это было бы multiprocessing.Value, а не multiprocessing.Manager().Value.Вы храните строку в серверном процессе менеджера и отправляете рассылки по соединениям TLS для доступа к значению.Кроме того, процесс сервера ограничен собственным GIL при обслуживании запросов.

Я не знаю, насколько каждый из этих аспектов вносит вклад в издержки, но в целом это дороже, чем чтение общей памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...