нужно держать в оперативке много данных (1.6 гб) и aiohttp server который передает эту функцию в ProcessPoolExecutor через asyncio.run_in_executor.
1) Правильно ли я понимаю что если у меня пул из 4 процессов то в любом случаи RAM usage будет 1.6*5 gb?
2) Даже если я ставлю размер пула 1 то в памяти создается 2 инстанса графа, я так понимаю первый создается при импорте модуля а второй при вызове функции в экзекюторе, можно ли как-то не загружать граф в главном процессе?
Вот кусочек кода и 'ps aux':
async def api(request):
data = await request.json()
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(pool, functools.partial(graph_search, data=data))sapronov 3138112 14.5 20.6 4415180 1644660 pts/3 Sl+ 10:01 0:07 python3 app.py
sapronov 3138116 0.9 20.8 4295692 1662696 pts/3 S+ 10:01 0:00 python3 app.py
Второй пункт решил заменой ProcessPoolExecutor на ThreadPoolExecutor, но все же, теперь получается у меня может ивент луп заблокироваться? Думаю было бы лучше все таки запускать в отдельном процессоре а в главном вообще в память не загружать граф. Буду очень благодарен за совет.
Граф векторов в 128 пространстве
а тебе надо, чтобы мастер процесс шарил память с процессами из ProcessPoolExecutor?
Да, если это возможно
Если нет, то мне было хватило одного сабпроцесса где будет в памяти граф, что бы не заблокировать eventloop
гугли multiprocessing SharedMemoryManager
если у тебя CPU bound то бесполезно использовать event loop, даже треды использовать бесполезно из-за GIL (но не в том случае, если по факту все вычислительные операции вызываются какими-то сишными функциями через питонячий программный интерфейс)
event loop у меня только для асинхронно сервера, то что треды только ухудшают производительность при CPU bound из за GIL я знаю, благодарю. Но если у меня в TheadPoolExecutor будет крутиться "тяжелая" функция она же не заблокирует ивент луп на 3 сек например? а будет прерываться и иногда отдавать управление ивент лупу, верно?
Я спросил с целью узнать, насколько большой процент операций у тебя именно графовые. Обходы там, поиски на графе и т.д. Если, скажем, бОльшая часть вычислительной сложности приходится на работу с отдельными нодами, а не с графом как с целым, имеет смысл разделить процессы по ролям. Одна роль — собственно хранители графа, способные получать команды (например через ту же очередь) и возвращать результат, другая — воркеры, которые что-то делают с нодами, но не держат граф в себе и всю нужную инфу запрашивают у графового процесса.
если делегировать выполнение CPU bound пулу процессов через run_in_executor? Если использовать TheadPoolExecutor, то из-за GIL будет и EventLoop в теории блокироваться
То что вы написали имеет конечно смысл, но я так глубоко не могу влезать, у меня есть либа с методами и все. https://github.com/nmslib/hnswlib
Какая разница, либа или не либа? Доступ к либе оборачивается в процесс, общаемся с ним через сообщения
Для поиска в графе нужно его полностью держать в памяти, попросить в ноды которая держит граф кусок этого графа нельзя
А что еще делает прога помимо поиска в графе?
Обсуждают сегодня