Как правильно работать с динамическим и статическим размещением кодера Matlab? - PullRequest
0 голосов
/ 18 марта 2019

Я недавно начал работать с Matlab-кодером для построения алгоритмов компьютерного зрения. Я работаю над проблемой классификации облаков точек, которая означает, что мои входные данные алгоритма представляют собой набор трехмерных точек (x, y, z), а мои выходные данные представляют собой массив переменных с классифицированными трехмерными точками.

Для этого проекта я решил использовать кодер Matlab. Кодер требует от разработчика указания верхней границы для выделения памяти. Ну, вот и проблема: набор входных 3D-точек может составлять до 250 тыс. Точек, а результат составляет ~ 50 тыс. Точек для каждого класса. В дополнение к этому моя реализация выделяет трехмерную сетку размером до: 600x600x120 (uint8) и еще несколько вспомогательной памяти, с которой я работаю. Я хочу сказать, что я работаю с большим объемом памяти.

Я пытался использовать статическое размещение; однако создается впечатление, что Matlab не построил статическое распределение памяти для случаев, когда каждое выделение памяти составляет около 1 МБ. Я установил верхний предел памяти на большое значение, а затем использовал Coder для генерации кода C ++ и скомпилировал его. При первом запуске алгоритма у меня было переполнение стека, а затем мне пришлось увеличить размер стека до 30 МБ (в Visual Studio), что кажется абсурдом.

С другой стороны, я мог бы использовать динамическое выделение памяти. Однако в этом случае почти все будет динамически распределено, что также является болью в шее из-за большого времени выделения и выделения ресурсов. Я хочу, чтобы Matlab написал код, который бы содержал внутри своей реализации ограниченную сверху память, которая не будет меняться между несколькими итерациями алгоритмов. (Так же, как член в классах C ++)

Я скажу более конкретно: в случае, если мой алгоритм использует сетку 600x600x120 и несколько изображений размером 600x600, я бы хотел, чтобы Matlab Coder генерировал код, который выделил бы эти воспоминания только один раз, и я бы использовал их на разных алгоритмические итерации.

У меня есть несколько вопросов:

  1. Как использовать последовательные выделения памяти между различными итерациями алгоритма. (Как избежать выделения и перераспределения на каждой итерации)

  2. Какой правильный размер стека я должен установить для статического выделения памяти (допустимо ли значение 1 МБ для статического выделения?)

  3. Я думал об использовании глобальной памяти для этого случая. Будет ли это работать?

  4. Любые предложения, как все уладить? Спасибо

Ответы [ 2 ]

1 голос
/ 20 марта 2019

Независимо от того, выделены ли локальные переменные в стеке, можно управлять с помощью параметра Использование пространства стека , который устанавливает ограничение на размер стека.

Если переменная не находится в стеке, переменные, как правило, «разливаются» как статические локальные переменные, которые выделяются один раз при инициализации программы. Тем не менее, включив параметр Re-entrant Code , вы получаете возможность одноразового динамического выделения большой памяти (а не статических локальных переменных).

Для получения дополнительной информации, пожалуйста, смотрите мой ответ на соответствующем посте Ответов MATLAB:

https://www.mathworks.com/matlabcentral/answers/450732-what-is-the-right-way-to-work-with-matlab-coder-dynamic-and-static-allocations

1 голос
/ 20 марта 2019

В итоге я использовал предельное значение стека по умолчанию, я увеличил порог динамического выделения памяти (в приложении кодера: Память -> порог динамического выделения памяти) до большого предела (~ 50 МБ).Затем я устанавливаю код генерации повторного входа (в приложении кодера: Память -> генерировать код повторного входа)

Вот ответ , полученный от Matlab:

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

Для обоих, установите Использование пространства стека достаточно маленьким, чтобы предотвратить подгонку локальных переменныхв стеке.Вариант A: используйте настройку стекового пространства.Это заставит эти переменные иметь «статический» класс хранения.Они выделяются один раз при запуске программы, и одна и та же память используется повторно при каждом вызове алгоритма.

Опция B. В дополнение к настройке стекового пространства включите MultiInstanceCode .Вместо статических локальных переменных создается тип, содержащий все потенциальные локальные переменные, слишком большие для стека.Перед вызовом алгоритма выделите это пространство один раз и передайте его сгенерированной функции C ++ при каждом вызове алгоритма.

...