Почему 352 ГБ NumPy ndarray можно использовать на компьютере MacOS с 8 ГБ памяти? - PullRequest
0 голосов
/ 02 марта 2019
import numpy as np

array = np.zeros((210000, 210000)) # default numpy.float64
array.nbytes

Когда я запускаю вышеуказанный код на моем MacBook с 8 ГБ памяти с macOS, ошибки не возникает.Но, выполняя тот же код на ПК с 16 ГБ памяти с Windows 10, или на ноутбуке Ubuntu с 12 ГБ памяти, или даже на суперкомпьютере Linux с 128 ГБ памяти, интерпретатор Python вызовет ошибку MemoryError.Во всех тестовых средах установлен 64-битный Python 3.6 или 3.7.

1 Ответ

0 голосов
/ 03 марта 2019

@ Martijn Pieters 'answer находится на правильном пути, но не совсем правильно: это не имеет ничего общего со сжатием памяти, а вместо этого связано с виртуальной памятью .

Например, попробуйте запустить на своем компьютере следующий код:

arrays = [np.zeros((21000, 21000)) for _ in range(0, 10000)]

Этот код выделяет 32 ТБ памяти, но вы не получите ошибку (по крайней мере, я этого не делал,в Linux).Если я проверяю htop, я вижу следующее:

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
31362 user       20   0 32.1T 69216 12712 S  0.0  0.4  0:00.22 python

Это потому, что ОС совершенно готова перегружать виртуальную память .На самом деле он не будет назначать страницы физической памяти, пока не понадобится.Вот как это работает:

  • calloc запрашивает у ОС некоторую память для использования
  • ОС просматривает таблицы страниц процесса и находит кусок памяти, который она желаетназначить.Это быстрая операция, ОС просто сохраняет диапазон адресов памяти во внутренней структуре данных.
  • программа записывает на один из адресов.
  • ОС получает сбой страницы , в этот момент он просматривает и фактически назначает страницу физической памяти. Размер страницы обычно составляет несколько килобайт .
  • ОС передает управление программе, которая продолжается, не замечая прерывания.

Создание одногоогромный массив не работает в Linux, потому что по умолчанию применяется эвристический алгоритм , чтобы выяснить, достаточно ли памяти доступно. ( спасибо @Martijn Pieters! ) Некоторые экспериментыв моей системе показывают, что для меня ядро ​​не желает предоставлять более 0x3BAFFFFFF байт.Однако, если я запускаю echo 1 | sudo tee /proc/sys/vm/overcommit_memory, а затем снова пытаюсь запустить программу в OP, она работает нормально.

Для развлечения попробуйте запустить arrays = [np.ones((21000, 21000)) for _ in range(0, 10000)].Вы обязательно получите ошибку нехватки памяти, даже на MacO или Linux с компрессией подкачки.Да, некоторые операционные системы могут сжимать оперативную память, но они не могут сжимать ее до уровня, при котором у вас не будет исчерпано памяти.

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