Почему Matlab работает все медленнее и медленнее при запуске программы, выполнение которой занимает много времени?

Есть программа, которую запускает мой матлаб, так как есть два гигантских вложенных цикла for, мы ожидаем, что эта программа будет работать более 10 часов. Мы просим Matlab распечатывать номер цикла каждый раз, когда он зацикливается.

Первоначально (первый 1 час) мы видим очень быстрое увеличение номера цикла на нашем экране; со временем он идет все медленнее и медленнее..... сейчас (более 20 часов подряд выполнения одного и того же файла «.m», и он еще не завершен), он почти в 20 раз медленнее, чем раньше был изначально.

Первоначально использование оперативной памяти составляло около 30%, сейчас, после 20 часов выполнения, это показано ниже: enter image  описание здесь


Спецификация моего компьютера ниже. введите здесь описание изображения

Что я могу сделать, чтобы Matlab сохранил свою первоначальную скорость?


person andy_tse    schedule 27.12.2014    source источник


Ответы (3)


Я могу только догадываться, но могу поспорить, что у вас есть некоторые переменные массива, которые не были предварительно выделены, и поэтому их размер увеличивается с каждой итерацией цикла for. В результате Matlab приходится перераспределять память на каждой итерации. Перераспределение замедляет работу, и тем более, чем больше эти переменные, потому что Matlab нужно найти все больший кусок непрерывной памяти. Это объясняет, почему программа работает медленнее с течением времени.

Если это действительно причина, решением будет предварительное выделение этих переменных. Если их размер заранее неизвестен, вы можете сделать предположение и предварительно выделить до приблизительного размера, таким образом избегая, по крайней мере, некоторого перераспределения. Или, если ваша программа не ограничена памятью, возможно, вы можете использовать верхнюю границу для размера переменной при предварительном выделении; затем, после цикла, обрежьте массивы, удалив неиспользуемые записи.

person Luis Mendo    schedule 27.12.2014
comment
@andy_tse. Если причина в этом, добавьте команду pack в начале ваш цикл объединит память (в основном дефрагментирует ее). Это приведет к небольшим накладным расходам, но его стоит протестировать, потому что следующая итерация с большей вероятностью найдет непрерывное пространство в памяти. - person Hoki; 27.12.2014
comment
@Hoki AFAIK, вы можете вызывать pack только из скриптов, а не из функций. - person Shai; 28.12.2014
comment
@Шай. Мой плохой, ты совершенно прав. pack не будет работать внутри функции. Хотя при желании ту же функциональность можно получить, сделав это вручную (сохранение рабочей области или громоздких переменных/очистка/перезагрузка). Этот публикация на сайте Matlab Central содержит подробности. - person Hoki; 29.12.2014

Некоторые общие советы, если они не помогают, я предлагаю добавить код в вопрос.

  1. Не выводить на консоль, этот вывод замедляет выполнение, а вывод сохраняется в памяти. Вместо этого напишите файл журнала, если он вам нужен. Для простого статуса используйте waitbar
  2. Убедитесь, что вы предварительно выделяете все переменные
  3. Проверьте, какие вызовы функций зависят от индекса цикла, например, увеличение размера переменных.
  4. Если используются какие-либо mex-функции, дважды проверьте их на наличие утечек памяти. Стандартная процедура для этого: вызовите функцию со случайными данными примера, не сохраняйте вывод. Если использование памяти увеличивается, в функции возникает утечка памяти.
  5. Используйте профайлер. Профилируйте свой код для первых n итераций (где n соответствует примерно 10 минутам), создайте отчет в формате HTML. Затем дайте ему поработать около 2 часов и снова сгенерируйте отчет для n итераций. Теперь сравните оба отчета и посмотрите, где теряется время.
person Daniel    schedule 27.12.2014

Я хотел бы указать всем на следующую страницу в документации MATLAB: Стратегии эффективного использования памяти. Эта страница содержит набор методов и рекомендаций, о которых должны знать пользователи MATLAB.

ОП напомнил мне об этом, когда сказал, что использование памяти имеет тенденцию со временем увеличиваться. Действительно, существует проблема с длительно работающими экземплярами MATLAB в системах win32, где существует утечка памяти, которая со временем усугубляется (это также описано в ссылке).

Я хотел бы добавить к ответу Луиса следующий совет, который мой друг однажды получил во время переписки с Яиром Альтманом:

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

Единственный верный способ решить проблему фрагментации памяти — перезапустить Matlab, а еще лучше — перезапустить Windows.

Дополнительную информацию о производительности выделения памяти можно найти в следующих недокументированных сообщениях Matlab:

person Dev-iL    schedule 24.01.2015
comment
но легко показать, что в некоторых случаях это действительно может быть вредно. Мне любопытно, почему это может быть вредно (и в каких случаях)? В статье, на которую вы ссылаетесь, эта опасность не упоминается. - person Hoki; 24.01.2015
comment
@Hoki - я не знаком с таким простым объяснением. Однако я добавил пару ссылок в свой ответ с немного дополнительной информацией о производительности предварительного распределения. - person Dev-iL; 24.01.2015