Использование оперативной памяти после импорта numpy в python 3.7.2 - PullRequest
0 голосов
/ 13 февраля 2019

Я запускаю conda 4.6.3 с python 3.7.2 win32.В Python, когда я импортирую NumPy, я вижу увеличение использования оперативной памяти на 80 МБ.Так как я использую многопроцессорность, мне интересно, нормально ли это, и есть ли способ избежать этой нагрузки на оперативную память?Ниже приведены все версии из соответствующих пакетов (из списка conda):

python ........... 3.7.2 h8c8aaf0_2

mkl_fft ........... 1.0.10 py37h14836fe_0

mkl_random..1.0.2 py37h343c172_0

numpy ........... 1.15.4 py37h19fb1c0_0

numpy-base..1.15.4 py37hc3f5095_0

спасибо!

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

[NumPy]: NumPy

является фундаментальным пакетом для научных вычислений с Python.

Это большой *Пакет 1010 *, предназначенный для работы с большими наборами данных и оптимизированный (прежде всего) по скорости.
Если вы посмотрите на его __ init __. Py (который выполняется при его импорте (например: import numpy)), вы заметите, что он импортирует множество элементов (пакетов / модулей):

  • Эти элементы сами могут импортировать другие
  • Некоторые из них модули расширения ( .pyd s ( .dll *)1025 * s) или .so s), которые загружаются в текущий процесс (также их зависимости)

Я подготовил демо.

code.py :

#!/usr/bin/env python3

import sys
import os
import psutil
#import pprint


def main():
    display_text = "This {:s} screenshot was taken. Press <Enter> to continue ... "
    pid = os.getpid()
    print("Pid: {:d}\n".format(pid))
    p = psutil.Process(pid=pid)
    mod_names0 = set(k for k in sys.modules)
    mi0 = p.memory_info()

    input(display_text.format("first"))

    import numpy

    input(display_text.format("second"))

    mi1 = p.memory_info()
    for idx, mi in enumerate([mi0, mi1], start=1):
        print("\nMemory info ({:d}): {:}".format(idx, mi))

    print("\nExtra modules imported by `{:s}` :".format(numpy.__name__))
    print(sorted(set(k for k in sys.modules) - mod_names0))
    #pprint.pprint({k: v for k, v in sys.modules.items() if k not in mod_names0})
    print("\nDone.")


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()

Выход :

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q054675983]> "e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code.py
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32

Pid: 27160

This first screenshot was taken. Press <Enter> to continue ...
This second screenshot was taken. Press <Enter> to continue ...

Memory info (1): pmem(rss=15491072, vms=8458240, num_page_faults=4149, peak_wset=15495168, wset=15491072, peak_paged_pool=181160, paged_pool=180984, peak_nonpaged_pool=13720, nonpaged_pool=13576, pagefile=8458240, peak_pagefile=8458240, private=8458240)

Memory info (2): pmem(rss=27156480, vms=253882368, num_page_faults=7283, peak_wset=27205632, wset=27156480, peak_paged_pool=272160, paged_pool=272160, peak_nonpaged_pool=21640, nonpaged_pool=21056, pagefile=253882368, peak_pagefile=253972480, private=253882368)

Extra modules imported by `numpy` :
['_ast', '_bisect', '_blake2', '_compat_pickle', '_ctypes', '_decimal', '_hashlib', '_pickle', '_random', '_sha3', '_string', '_struct', 'argparse', 'ast', 'atexit', 'bisect', 'copy', 'ctypes', 'ctypes._endian', 'cython_runtime', 'decimal', 'difflib', 'gc', 'gettext', 'hashlib', 'logging', 'mtrand', 'numbers', 'numpy', 'numpy.__config__', 'numpy._distributor_init', 'numpy._globals', 'numpy._import_tools', 'numpy.add_newdocs', 'numpy.compat', 'numpy.compat._inspect', 'numpy.compat.py3k', 'numpy.core', 'numpy.core._internal', 'numpy.core._methods', 'numpy.core._multiarray_tests', 'numpy.core.arrayprint', 'numpy.core.defchararray', 'numpy.core.einsumfunc', 'numpy.core.fromnumeric', 'numpy.core.function_base', 'numpy.core.getlimits', 'numpy.core.info', 'numpy.core.machar', 'numpy.core.memmap', 'numpy.core.multiarray', 'numpy.core.numeric', 'numpy.core.numerictypes', 'numpy.core.records', 'numpy.core.shape_base', 'numpy.core.umath', 'numpy.ctypeslib', 'numpy.fft', 'numpy.fft.fftpack', 'numpy.fft.fftpack_lite', 'numpy.fft.helper', 'numpy.fft.info', 'numpy.lib', 'numpy.lib._datasource', 'numpy.lib._iotools', 'numpy.lib._version', 'numpy.lib.arraypad', 'numpy.lib.arraysetops', 'numpy.lib.arrayterator', 'numpy.lib.financial', 'numpy.lib.format', 'numpy.lib.function_base', 'numpy.lib.histograms', 'numpy.lib.index_tricks', 'numpy.lib.info', 'numpy.lib.mixins', 'numpy.lib.nanfunctions', 'numpy.lib.npyio', 'numpy.lib.polynomial', 'numpy.lib.scimath', 'numpy.lib.shape_base', 'numpy.lib.stride_tricks', 'numpy.lib.twodim_base', 'numpy.lib.type_check', 'numpy.lib.ufunclike', 'numpy.lib.utils', 'numpy.linalg', 'numpy.linalg._umath_linalg', 'numpy.linalg.info', 'numpy.linalg.lapack_lite', 'numpy.linalg.linalg', 'numpy.ma', 'numpy.ma.core', 'numpy.ma.extras', 'numpy.matrixlib', 'numpy.matrixlib.defmatrix', 'numpy.polynomial', 'numpy.polynomial._polybase', 'numpy.polynomial.chebyshev', 'numpy.polynomial.hermite', 'numpy.polynomial.hermite_e', 'numpy.polynomial.laguerre', 'numpy.polynomial.legendre', 'numpy.polynomial.polynomial', 'numpy.polynomial.polyutils', 'numpy.random', 'numpy.random.info', 'numpy.random.mtrand', 'numpy.testing', 'numpy.testing._private', 'numpy.testing._private.decorators', 'numpy.testing._private.nosetester', 'numpy.testing._private.pytesttester', 'numpy.testing._private.utils', 'numpy.version', 'pathlib', 'pickle', 'pprint', 'random', 'string', 'struct', 'tempfile', 'textwrap', 'unittest', 'unittest.case', 'unittest.loader', 'unittest.main', 'unittest.result', 'unittest.runner', 'unittest.signals', 'unittest.suite', 'unittest.util', 'urllib', 'urllib.parse']

Done.

И ( перед и после импорта) снимки экрана ( [MS.Docs]: Process Explorer ):

Img0 - before

Img1 - after

Как личное замечание, я думаю, что ~ 80 МиБ (или что бы то ни было точная сумма) более чем прилично для текущего "эпоха ", которая характеризуется смехотворно большим количеством аппаратных ресурсов, особенно в области памяти.
Кроме того, это, вероятно, будет незначительным по сравнению с количеством, требуемым самими массивами.Если это не так, вам, вероятно, следует подумать о том, чтобы отойти от numpy .

. Можно уменьшить объем памяти, выборочно импортируя только те модули, которые содержат нужные вам функции.(мой личный совет против этого), и, таким образом, обходя __ init __. py :

  • Вы должны быть экспертом в numpy internals
  • Модули необходимо импортировать «вручную» (по имени файла), используя [Python 3]: importlib - Реализация импорта (или альтернативы)
  • Их иждивенцы также будут импортированы / загружены (и из-за этого я не знаю, сколько свободной памяти вы получите)
0 голосов
/ 13 февраля 2019

Вы не можете избежать этой стоимости, но она, вероятно, не так плоха, как кажется.Библиотеки numpy (копия только C libopenblasp плюс все модули расширения Python numpy) занимают более 60 МБ на диске, и все они будут отображаться в памяти вашего процесса Python при импорте;добавление ко всем модулям Python и динамически выделяемой памяти, участвующей в загрузке и инициализации всех из них, и 80 МБ увеличенного зарегистрированного использования ОЗУ вполне нормальное явление.

При этом:

  1. Библиотеки C и модули расширения Python отображаются в памяти, но это не означает, что они занимают «реальную» оперативную память;если пути к коду на данной странице не выполняются, страница либо никогда не будет загружена, либо будет отброшена под давлением памяти (даже не записана в файл подкачки, поскольку она всегда может перезагрузить ее из исходной DLL).
  2. В UNIX-подобных системах, когда вы fork (multiprocessing делает это по умолчанию везде, кроме Windows), эта память распределяется между родительским и рабочим процессами в режиме копирования при записи.Поскольку сам код, как правило, не пишется, единственной ценой являются сами таблицы страниц (крошечная доля памяти, на которую они ссылаются), и родительский и дочерний разделы будут совместно использовать эту оперативную память.

К сожалению, наWindows, fork не подходит (если только вы не используете Ubuntu bash в Windows, и в этом случае это всего лишь Windows, то есть Linux), так что вы, вероятно, будете платить больше затрат памяти в каждом процессе.Но даже там libopenblasp, библиотека C, поддерживающая большие части numpy, будет переназначаться для каждого процесса, но ОС должна правильно распределять эту доступную только для чтения память между процессами (и большими частями, если не всеми, Pythonтакже модули расширения).

В принципе, пока это не вызовет проблемы (и вряд ли это так), не беспокойтесь об этом.

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