Большие проблемы с памятью матрицы

1

У меня есть два вопроса, но первое имеет преимущество.

Я проводил некоторое время для тестирования некоторых основных операций с numpy, которые будут иметь отношение ко мне.

Я сделал следующее

n = 5000
j = defaultdict()
for i in xrange(n):
    print i
    j[i] = np.eye(n)

Случилось так, что память python почти сразу же снимается до 6 гигабайт, что составляет более 90% моей памяти. Однако цифры печатались неуклонно, около 10-20 в секунду. В то время как номера печатались, память использовала спорадически отскок до ~ 4 концертов и обратно до 5, назад до 4, до 6, до 4,5 и т.д. И т.д. На 1350 итерациях у меня была ошибка сегментации.

Итак, мой вопрос: что на самом деле произошло за это время? Действительно ли эти матрицы созданы по одному за раз? Почему использование памяти происходит вверх и вниз?

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

Если мне действительно нужны 5000 5000x5000 матриц, возможно ли это с 6 гигабайтами памяти? Я не знаю, что можно сделать со всеми имеющимися инструментами и трюками... Может быть, мне просто нужно будет хранить некоторые из них на диске и вытаскивать их в куски?

Любые советы, если мне нужно пройти через многие матрицы и выполнить базовую арифметику между ними?

Спасибо.

Теги:
arrays
numpy
matrix
memory-management

1 ответ

1
Лучший ответ

Если мне действительно нужны 5000 5000x5000 матриц, возможно ли это с 6 гигабайтами памяти?

Если они плотные матрицы, и вам нужны они все в одно и то же время, а не надолго. Рассматривать:

5K * 5K = 25M cells
25M * 8B = 200MB (assuming float64)
5K * 200MB = 1TB

Матрицы создаются по одному за раз. Когда вы приближаетесь к 6 ГБ, что происходит, зависит от вашей платформы. Он может начать замену на диск, замедляя вашу систему до обхода. Там может быть своп с фиксированным или максимальным размером, поэтому в конечном итоге у него все еще не хватает памяти. Он может делать предположения о том, как вы собираетесь использовать память, предполагая, что в памяти всегда найдется место, чтобы соответствовать вашему фактическому рабочему набору в любой момент времени, только для segfault, когда он обнаруживает, что он не может. Но единственное, что он не собирается делать, это просто работать эффективно.


Вы говорите, что большинство ваших матриц редки. В этом случае используйте одно из разреженных матричных представлений. Если вы знаете, какой из 5000 будет плотным, вы можете смешивать и сопоставлять плотные и разреженные матрицы, но если нет, просто используйте тот же разреженный тип матрицы для всего. Если это означает, что ваши случайные плотные матрицы принимают 210 МБ вместо 200 МБ, но все остальные твои матрицы принимают 1 МБ вместо 200 МБ, что более чем стоит как компромисс.


Кроме того, вам действительно нужно работать на всех 5000 матрицах сразу? Если вам понадобится, скажем, текущая матрица и предыдущая на каждом шаге, вы можете генерировать их на лету (или читать с диска "на лету"), и вам нужно только 400 МБ вместо 1 ТБ.


В худшем случае вы можете эффективно обменивать вещи вручную, с какой-то дисциплиной кэширования, как и в наименее недавнем использовании. Вы можете легко сохранить, скажем, последние 16 матриц в памяти. Держите грязный флаг на каждом, чтобы вы знали, нужно ли его сохранять, когда он смывает его, чтобы освободить место для другой матрицы. Это так сложно, как это получится.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню